LoginSignup
7
5

More than 1 year has passed since last update.

【Flutter】CheckBoxListTileとTextStyleを活用してToDoリストのフロントエンドを作ってみた

Last updated at Posted at 2021-08-13

はじめに

先日からFlutterを使い始めた初心者です。
制作したいToDoアプリの完成形のイメージは自分の中であるので、それらを実現するために色々調べているので、それらをまとめていきます!
何かおかしな点などがありましたらコメントをお願いします。

この記事で分かること

完成形はこんな感じ

スクリーンショット 2021-08-13 222231.png

この記事では主に

  • CheckBoxListTileについて
  • 取り消し線の実装方法

をまとめています

ToDoリストのフロントエンドを作る

そもそものお話

今回のゴールは

  • 各リストの左側にチェックボックスを入れる
  • チェックしたら取り消し線が入る

ことです。
私のイメージではListTileを使ってleading: Iconみたいな感じでCheckBoxを入れるのかなーと思ってたのですが、調べていくとどうやらCheckBoxListTileを使うらしい。

私は習うより慣れよ派なのでとりあえずコードを写していろいろいじっていきましょう。

CheckBoxListTileを実装する

以下のコードをmain.dartにコピペしてください。
(このコードはこちらのサイトを参考にしました)

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),
    ];
  }
}

実行してみると…
スクリーンショット 2021-08-13 215601.png
こんな感じ。とりあえず各リストにチェックボックスを入れることが出来ました!

改善する

チェックボックスを左側にする

先ほどのコードではチェックボックスが右側になってしまっているので、これを左側に移しましょう。
以下のコードをCheckboxListTileのカッコの中に入れるだけでOKです!
(これはFlutter Doc JPのサイトを参考にしました)

controlAffinity: ListTileControlAffinity.leading,

実行するとこんな感じ
スクリーンショット 2021-08-13 220914.png

取り消し線を入れる

だいぶイメージ通りになってきました!次はチェックを入れたら取り消し線が入るようにしましょう。
取り消し線を入れるのはあくまでチェックした時だけです。なので使うコードは以下になります。
(後ほどコードを全文載せます)

decoration: checkBoxListTileModel[index].isCheck ? TextDecoration.lineThrough : TextDecoration.none,

これをTextStyleの中に入れて実行すると

スクリーンショット 2021-08-13 222231.png

出来たーーー!!これで完成です。

完成形のコード

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(
                        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),
    ];
  }
}

今回特に参考にさせていただいたサイト

おわりに

思っていたものが実装出来て良かったです!

ここまで読んでいただきありがとうございました。何かありましたらコメントをお願いします。

7
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
5