【Flutter入門】Flutterで簡単なTODOアプリを作る。statefulWidget使用
皆さんこんにちは。先日社内向け勉強会でFlutterのハンズオンをしました。その際にstatefulWidgetを使ってTODOアプリを作成しました。その解説を行います。最終的にはとても簡単なTODOアプリが完成します!
ソースコードは記事の最後に載せています。
Flutterを使ってTODOアプリを作成するよ。
それでは早速参ります。
完成系はこんな感じです。
機能としては以下です。
- 右下のプラスアイコンをクリックしてTODOを追加できる
- TODOに文字を入力できる。文字列の編集もできる。
- TODOにチェックできる
- TODOがチェック状態なら取り消し線にする
FlutterのWidgetという概念について
Flutterを作ったGoogleが提唱していることですが、"Everything is a Widget" すべてはWidgetということです。
ボタンでもテキストでも枠組みでも、全てWidgetというものです。簡単に言えばUIパーツといえるでしょうか。すべてWidgetクラスを継承しています。
Widgetの大まかな種類
こちらのサイトで紹介されていた画像です。わかりやすかったです。Widgetを4つの種類に分けて考えています。画面の部品パーツはそのうちの1つです。他に、アプリ全体に関するWidgetや、画面の土台になるWidgetや、パーツの並べ方に関するWidgetがあります。
スタイルシートでいうところの、marginやpositionなどもこのWidgetで表現します。
Widgetツリーについて
Widgetツリーについて簡単に説明をします。Web開発でいうとDOMツリーのようなものです。Flutterの内部にはWidgetツリーというものがあり、これが画面を形成しています。正確にはelementツリーを生成しているようですがここでは割愛します。
ルートには、MyAppがあります。これはDOMツリーでいうところdocumentのようなものでしょうか(?)。
その配下には、MaterialAppとScafoldがあり、画面の土台を形成しています。その下に、かく部品などがぶら下がっているイメージです。
Flutterでの状態管理の概念
モダンなjsフレームワークではstate管理機能があります。状態管理機能ですね。Flutterにもそれがあります。
初学者はまず、statelessWidgetと、statefulWidgetを使うようです。学習するにつれて、他に別のもので管理するようですが・・・。今回のTODOアプリではリストを追加したあとに、その追加したことを画面に反映させたいのでstatefulWidgetを使用します。
TODOアプリをコーディングしていく
さっそくTODOアプリを作っていきましょう。まずはソースコードを貼り付けちゃいます。コメントを適当に書いています。
↓main.dart
import 'package:flutter/material.dart'; import 'package:my_app/todo.dart'; void main() { // runApp関数でウィジェットツリーのルートとなる。 runApp(const App()); } class App extends StatelessWidget { const App({Key? key}) : super(key: key); // stateLessWidget または stateFulWidgetを継承した場合は必ずbuildメソッドをオーバーライドしないといけない。 @override Widget build(BuildContext context) { return const MaterialApp( home: HomeScreen(), ); } } // 途中で値が変わったらそれを反映させる必要があるのでStatefulWidgetを記載する class HomeScreen extends StatefulWidget { const HomeScreen({Key? key}) : super(key: key); // StatefulWidgetはWidgetにstateの概念をいれて拡張したもの // StatefulWidgetはcreateStateメソッドを持ち、これがStateクラスを返す @override ////stateを継承している型 _HomeScreenState createState() => _HomeScreenState(); } class _HomeScreenState extends State<HomeScreen> { // 初めに3つTODOリストを作成 final _todos = List.generate( 3, (index) => ToDo(), ); @override Widget build(BuildContext context) { // scaffold:足場 return Scaffold( appBar: AppBar( title: const Text('Harumaki ToDo'), backgroundColor: const Color(0xFF388E3C), ), // ListView.builder()は基本的なリストを作成する body: ListView.builder( //生成する個数を指定する itemCount: _todos.length, // ↓itemBuilderの関数型の定義 Widget型を返す 引数にはこれら↓ // IndexedWidgetBuilder = Widget Function(BuildContext context, int index); // CheckboxListTileについて 公式 https://api.flutter.dev/flutter/material/CheckboxListTile-class.html itemBuilder: (BuildContext context, int index) { return ListTile( leading: Checkbox( value: _todos[index].checked, onChanged: (e) { setState(() { _todos[index].checked = e; //イベントeを受け取り反映 true, false }); }, ), title: TextFormField( style: _todos[index].checked == true ? const TextStyle(decoration: TextDecoration.lineThrough) // 取り消し線 : const TextStyle(color: Colors.black), // falseの時はただの黒色 ), ); }, ), floatingActionButton: FloatingActionButton( child: const Icon(Icons.add), backgroundColor: const Color(0xFF388E3C), onPressed: () { // setState()を呼び出すことで裏では再度buildメソッドを呼び出して変更された変数で再描画している setState(() { _todos.add( ToDo(), ); }); }, )); } }
↓todo.dart (TODOクラス)
import 'package:flutter/material.dart'; class ToDo { String title; bool? checked; ToDo([this.title = "", this.checked = false]); }
上記、main.dartとtodo.dartがあれば今回のTODOアプリはできます。同じlibフォルダの中にmain.dartとtodo.dartはいれてください。
各コードの説明を簡単についてはコメントで記載しています。参考にしてみてください。
コードをコピペしてflutter run すれば簡単なTODOアプリが完成すると思います。
まとめ
今回はstatefulWidgetを使って簡単なTODOアプリを作成しました。
いろんなWidgetがあるので公式サイトをみてみてくださいね。
少しでもお役に立てたら幸いです。ではまた。最後まで読んでいただきありがとうございました。