はじめに
先日からFlutterを使い始めた初心者です。
制作したいToDoアプリの完成形のイメージは自分の中であるので、それらを実現するために色々調べているので、それらをまとめていきます!
何かおかしな点などがありましたらコメントをお願いします。
この記事で分かること
完成形はこんな感じ
この記事では主に
- CheckBoxListTileについて
- 取り消し線の実装方法
をまとめています
ToDoリストのフロントエンドを作る
そもそものお話
今回のゴールは
- 各リストの左側にチェックボックスを入れる
- チェックしたら取り消し線が入る
ことです。
私のイメージではListTileを使ってleading: Iconみたいな感じでCheckBoxを入れるのかなーと思ってたのですが、調べていくとどうやらCheckBoxListTileを使うらしい。
私は習うより慣れよ派なのでとりあえずコードを写していろいろいじっていきましょう。
CheckBoxListTileを実装する
以下のコードをmain.dartにコピペしてください。
(このコードはこちらのサイトを参考にしました)
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
List<CheckBoxListTileModel> checkBoxListTileModel =
CheckBoxListTileModel.getUsers();
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
centerTitle: true,
title: new Text(
'CheckBox ListTile Demo',
style: TextStyle(color: Colors.black),
),
),
body: new ListView.builder(
itemCount: checkBoxListTileModel.length,
itemBuilder: (BuildContext context, int index) {
return new Card(
child: new Container(
padding: new EdgeInsets.all(10.0),
child: Column(
children: <Widget>[
new CheckboxListTile(
activeColor: Colors.pink[300],
dense: true,
//font change
title: new Text(
checkBoxListTileModel[index].title,
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.w600,
letterSpacing: 0.5),
),
value: checkBoxListTileModel[index].isCheck,
secondary: Container(
height: 50,
width: 50,
),
onChanged: (bool? val) {
itemChange(val!, index);
})
],
),
),
);
}),
);
}
void itemChange(bool val, int index) {
setState(() {
checkBoxListTileModel[index].isCheck = val;
});
}
}
class CheckBoxListTileModel {
int userId;
String title;
bool isCheck;
CheckBoxListTileModel({required this.userId, required this.title, required this.isCheck});
static List<CheckBoxListTileModel> getUsers() {
return <CheckBoxListTileModel>[
CheckBoxListTileModel(
userId: 1,
title: "Android",
isCheck: true),
CheckBoxListTileModel(
userId: 2,
title: "Flutter",
isCheck: false),
CheckBoxListTileModel(
userId: 3,
title: "IOS",
isCheck: false),
CheckBoxListTileModel(
userId: 4,
title: "PHP",
isCheck: false),
CheckBoxListTileModel(
userId: 5,
title: "Node",
isCheck: false),
];
}
}
実行してみると…
こんな感じ。とりあえず各リストにチェックボックスを入れることが出来ました!
改善する
チェックボックスを左側にする
先ほどのコードではチェックボックスが右側になってしまっているので、これを左側に移しましょう。
以下のコードをCheckboxListTileのカッコの中に入れるだけでOKです!
(これはFlutter Doc JPのサイトを参考にしました)
controlAffinity: ListTileControlAffinity.leading,
取り消し線を入れる
だいぶイメージ通りになってきました!次はチェックを入れたら取り消し線が入るようにしましょう。
取り消し線を入れるのはあくまでチェックした時だけです。なので使うコードは以下になります。
(後ほどコードを全文載せます)
decoration: checkBoxListTileModel[index].isCheck ? TextDecoration.lineThrough : TextDecoration.none,
これをTextStyleの中に入れて実行すると
出来たーーー!!これで完成です。
完成形のコード
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
List<CheckBoxListTileModel> checkBoxListTileModel =
CheckBoxListTileModel.getUsers();
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
centerTitle: true,
title: new Text(
'CheckBox ListTile Demo',
style: TextStyle(color: Colors.black),
),
),
body: new ListView.builder(
itemCount: checkBoxListTileModel.length,
itemBuilder: (BuildContext context, int index) {
return new Card(
child: new Container(
padding: new EdgeInsets.all(10.0),
child: Column(
children: <Widget>[
new CheckboxListTile(
controlAffinity: ListTileControlAffinity.leading,
activeColor: Colors.pink[300],
dense: true,
//font change
title: new Text(
checkBoxListTileModel[index].title,
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.w600,
letterSpacing: 0.5,
decoration: checkBoxListTileModel[index].isCheck ? TextDecoration.lineThrough : TextDecoration.none,
),
),
value: checkBoxListTileModel[index].isCheck,
secondary: Container(
height: 50,
width: 50,
),
onChanged: (bool? val) {
itemChange(val!, index);
})
],
),
),
);
}),
);
}
void itemChange(bool val, int index) {
setState(() {
checkBoxListTileModel[index].isCheck = val;
});
}
}
class CheckBoxListTileModel {
int userId;
String title;
bool isCheck;
CheckBoxListTileModel({required this.userId, required this.title, required this.isCheck});
static List<CheckBoxListTileModel> getUsers() {
return <CheckBoxListTileModel>[
CheckBoxListTileModel(
userId: 1,
title: "Android",
isCheck: true),
CheckBoxListTileModel(
userId: 2,
title: "Flutter",
isCheck: false),
CheckBoxListTileModel(
userId: 3,
title: "IOS",
isCheck: false),
CheckBoxListTileModel(
userId: 4,
title: "PHP",
isCheck: false),
CheckBoxListTileModel(
userId: 5,
title: "Node",
isCheck: false),
];
}
}
今回特に参考にさせていただいたサイト
- https://medium.com/flutterdevs/checkbox-listtile-in-flutter-50e877cee48c (メインコード)
- https://flutter.ctrnost.com/basic/interactive/form/checkbox/ (チェックボックスについて)
- https://uki-home.xyz/2020/04/01/1742/ (TextStyleについて)
おわりに
思っていたものが実装出来て良かったです!
ここまで読んでいただきありがとうございました。何かありましたらコメントをお願いします。