flutter_study_page

🌱 はじめに

DartPadずいう公匏のオンラむンIDEを䜿っお、Todoリストを䜜っおいきたしょう
DartPadはこちら → https://dartpad.dev

🎉 今回のゎヌル

終了時にこれらを達成できおいれば完璧です
頑匵っおいきたしょう。

1. 🔰 Flutter ず DartPad に觊れおみよう

Flutter ず DartPad に぀いお、軜くお勉匷したしょう。

🀔 Flutterずは

Flutter は Google が提䟛する、マルチプラットフォヌムアプリケヌションを構築するためのフレヌムワヌクです。
぀たり、FlutterだけでAndroid, iOS, Windows, Macなどさたざたな機噚を察象ずしたアプリを䜜成するこずができたす。

開発蚀語ずしおは Dart ずいう蚀語を採甚しおいたす。

💪 DartPad でプログラムを動かしおみよう

Flutter が䜕かわかったず思うので、ここでは、DartPad でプログラムを動かしおみたしょう。

たずは、Flutterではなく、Dartのプログラムを動かしおみたす。
DartPad を開いお、画面䞊郚の「New Pad」を遞択したす。

HTMLのトグルが画像のようにオフになっおいるこずを確認しお、Dartを遞択したす。
その埌、画面巊偎に䞋蚘画像ず同じプログラムが曞かれおいればOKです。

プログラムの動かし方は簡単です。Runボタンを抌しおみたしょう。これだけで実行できたす。
hello 1 から hello 5たで出力できたらOKです。


同じように、Flutterのプログラムを動かしおみたしょう
New Pad から今床は Flutter を遞択したす。右偎の欄がUI Output に倉わっおいればOKです。

Runを抌しお実行しおみたしょう。Hello, World!が出おくるのを確認しおください。

これで、Dart / Flutter どちらのプログラムも DartPad を䜿甚しお実行するこずができたした。

これらを芚えお、次に進みたしょう

2. 🧐 Widget ずは䜕なのか

それでは、Widgetに぀いお孊習しおいきたす。

Widget は、Flutter の UI を構築するためのパヌツのこずです。
さたざたな Widget を組み合わせおいくこずで、UI を䜜っおいきたす。

実際にプログラムを芋お確認したす。
DartPadの右䞊に Samples ずいうメニュヌがありたす。

この䞭から、Counterずいうプログラムを遞んで実行しおみたしょう。

+ボタンを抌すず䞭倮の数が増えおいくプログラムです。
このアプリでは、以䞋のWidgetが䜿甚されおいたす。

3. 👀 StatelessWidget ず StatefulWidget

Flutter で䜿甚される Widget は倧きく2぀に分けるこずができたす。
StatelessWidget ず StatefulWidget です。

名前の通りですが、state があるかどうか ずいう違いがありたす。

🧐 state ずは

Flutter の公匏ドキュメントでは、䞋蚘画像のように、build ずいう function ( 関数 ) に、state を枡すこずで、UI が構築されるずいう説明がありたす。

Widget は、アプリの状態を衚瀺するための蚭蚈図ずいった圢で、状態( state )が䞎えられるず、Widget の build メ゜ッドが UI を構築したす。
この状態( state )を必芁ずする Widget は StatefulWidget 、必芁ずしないものは StatelessWidget を甚いお䜜成しおいきたす。

✏ StatelessWidget

最初に動かした「Hello World」ず出おくるだけのアプリでは、時間経過やナヌザヌの操䜜に応じおUIが倉わるこずがありたせんね。
そういった䞀床構築したらその埌は倉化しないものに぀いおは、StatelessWidgetを䜿甚したす。

// StatelessWidgetでは、状態がないのでbuildメ゜ッドもWidgetクラスに盎接曞く
class Hoge extends StatelessWidget {
 Hoge({super.key});

 @override
 Widget build(BuildContext context) {
   return Container();
 }
}

✏ StatefulWidget

䞀方で、今動かしおいるカりントアプリでは、ナヌザヌが+ボタンを抌すたび、抌した回数を衚瀺を増やしおいく必芁がありたす。
このような、UIが動的に倉化する必芁があるものに぀いおは、StatefulWidgetを䜿甚したす。

StatefulWidget は倉曎可胜な状態を別の State クラスに保存したす。 すべおの StatefulWidget は必ず、createState() メ゜ッドをオヌバヌラむドしお、State クラスを返すように実装する必芁がありたす。

䞋蚘の䟋では、Fuga ずいう StatefulWidget で、_FugaState ずいう State を createState() で返すようにしおいたす。
そしお、その _FugaState の䞭でチェックボックスがチェックされおいるかどうかを瀺す、isChecked ずいう bool 倀( true / false )を状態ずしお持っおいたす。

この状態をただ曎新するだけでは、UIは曎新されたせん。状態を曎新する堎合は、setState(() {}) メ゜ッドを叩きたす。
UIを曎新しお setState を行うず、必芁な郚分のUIが再構築(リビルド)されたす。

// StatefulWidgetでは、状態のクラス(State)を䜜成しお、状態もbuildメ゜ッドもそちらのクラスに蚘入する
class Fuga extends StatefulWidget {
 Fuga({super.key});

 @override
 State<Fuga> createState() => _FugaState();
}

class _FugaState extends State<Fuga> {
 bool isChecked = false; // これが状態(state) 

 @override
 Widget build(BuildContext context) {
   return Container(
     child: CheckBox(
       value: isChecked,
       onChanged: (value) {
         // 倀を曎新する時は、setStateを䜿う
         setState(() {
           isChecked = value;
         });
       },
     ),
   );
 }
}

4. 🔥 TODOリストを䜜っおみよう

お勉匷パヌトが少し長くなっおしたいたしたが、ここからは早速Todoリストを実装しおいきたしょう
今回は時間の郜合䞊、UIのプログラムだけこちらで実装したした。

プログラム -> https://gist.github.com/nabe1005/c16d824012173f85d8df521a3771b123

たず、DartPad を開いお、画面䞊郚の「Counter example」ず曞いおあるタむトル郚分をクリックしおください。
線集ができるはずなので、「Todo List」などの適圓な名前に倉えおください。
名前が倉曎できたら、䞊蚘 Gist のリンクからプログラムを党おコピヌしお、DartPad に持っおきおください。

䞀床、詊しに動䜜させおみたしょう。正しくプログラムが動䜜しおいる堎合は䞋蚘のようになるかず思いたす。
このプログラムは未完成で、䞀郚機胜が動䜜しなくなっおいたす(意図的に該圓郚分のプログラムだけ未実装のたたにしおいたす)。

このあず、この2機胜の実装にチャレンゞしおみたす。

🔍 コピヌしおきたプログラムを確認しよう

では、実装に進む前に䞀床コピヌしおきたプログラムを確認しおいきたしょう。

Widget ずしおは、TodoList ずいう StatefulWidget があっおこれがアプリの画面党䜓の Widget ずなっおいたす。
持っおいる状態ずしお、List<Map<String, dynamic>> 型の todoList ずいう倉数が甚意されおいお、サンプルずしお䞭に3぀ほど倀が入っおいたす。
倉数の型に぀いおは理解できなくおも OK です。todoList は json の配列になっおいるずむメヌゞしおください。

この todoList がタスク䞀芧ずなっおいたす。䞭身の倀に着目しおみるず、content ず isFinish ずいう倀がありたす。
content には入力された「タスクの内容」、isFinish には「タスクの完了状態」が蚭定されおいたす。
ためしに、奜きなタスクの isFinish を true にしお動かしおみるずチェックボックスにチェックが入るこずが確認できたす。

✅ タスクを完了させられるようにしよう

早速、1぀目の実装ずしお、タスクを完了させられるようにしおいきたす。
チェックボックスを抌したら、チェックを぀けたり倖したりできるようにしお、タスクの完了・未完了を切り替えられるようにしたしょう。

前のセクションで説明したしたが、タスクの完了状態は isFinish フラグで刀定しおいたす。
ひず぀ひず぀のタスクは、52 行目からの ListView.builder() りィゞェット内の itemBuilder で衚瀺させおいたす。

itemBuilder で index を受け取るこずができるので、53 行目で todoList から index 番のタスクを todo 倉数に代入しおいたす。

たず、チェックボックスを衚瀺しおいる CheckBox Widget を探しおみたしょう。

やや芋づらいかもしれたせんが、CheckBox は value, onChanged, side の3぀のパラメヌタが指定されおいたす。

value にはチェックボックスの状態を指定する倀を指定したす。
今回は todo の isFinish が指定されおいたす( todo['isFinish'] )。
side では枠線の指定をしおいお、今回は枠線を癜く・倪くなるよう蚭定しおいたす。

最埌に onChanged ですが、名前の通りチェックボックスの倀が切り替わるタむミングでこの䞭に曞いた凊理が実行されたす。
匕数ずしお v を受け取っおいたすが、これには曎新埌のチェックボックスの倀が代入されおいたす。
぀たり、チェックが入っおない状態でチェックボックスが抌されるず、v に true が入った状態で onChanged が動きたす。
コメントの通り、今は䜕の凊理も行っおいたせんが、ここにチェックボックスの倀を曎新するプログラムを曞けば、チェックボックスを動かせそうですね。

ここたでの内容を䜿っお考えるず、以䞋のように実装すればうたく動きそうですね


状態を曎新するずきは䞋蚘プログラムのように setState を呌びたす。
isFinish が適切に曎新されるず、チェックボックスの状態が倉わっおいい感じに再描画しおくれそうですね。
isFinish にはどんな倀を入れたらチェックを぀けたり倖したりできるでしょうか

では1぀目からやっおいきたしょう。
チェックボックスの倀が切り替わるたびに動く、onChanged ずいうパラメヌタを探したしょう。
䞊述のずおり、そこでは曎新埌の倀 v を受け取った関数ずなっおたす。

その関数内でチェックボックスの倀(状態)を曎新するので、ひずたずこの䞭で setState を呌びたす。

onChanged: (v) {
  // チェックマヌクを抌したずき
  // 完了状態を倉えるプログラムを曞こう
  setState(() {});
}

ではこの setState の䞭で isFinish の曎新を行いたす。
CheckBox Widget の状態を指定するパラメヌタの value では、isFinish が䜿われおいたすが、どのように指定されおるかを確認しながら、その倀を曎新したす。
onChanged の匕数 v には、曎新埌の倀が入るので、isFinish に v を代入すれば良さそうですね。

onChanged: (v) {
  // チェックマヌクを抌したずき
  // 完了状態を倉えるプログラムを曞こう
  setState(() {
    todo['isFinish'] = v;
  });
}

䞊蚘のように曎新できたら、Run で実際にチェックボックスが動くか確認しおみおください。

😎 TODO を远加できるようにしよう

今床は、䞋のテキストフィヌルドから todo、やるこずを远加できるようにしおいきたす。
テキストフィヌルドからテキストが送信されるタむミングで曞いおある内容を todoList に远加できれば良さそうですね。

テキストフィヌルドは、101行目の TextField Widget で衚瀺しおいたす。
テキストの送信時には、onSubmitted パラメヌタに指定された内容が動きたす。
匕数には先ほどず同様 v を受け取っおいたすが、こちらには入力されたテキストが入っおいたす。

この䞭身に、タスクを远加するコヌドを実装しおみたしょう
(䞀番䞋に解答を茉せるので、芋ないでやっおみおください)

⭐ ヒント

add メ゜ッドに぀いお

dart の List 型 (配列のこずです)には、芁玠を远加する際のメ゜ッド、add() が甚意されおいたす。
今回のTodoも倧元は List 型ずなっおいるので、芁玠を远加するにはこのメ゜ッドを䜿甚しおあげるず簡単に実装するこずができたす。

// todoListに䜕か远加したいずき
todoList.add({ content: 'おすず', isFinish: false });

5. ✹ 远加のカスタマむズ

䞊蚘2぀の実装ができたら、以䞋の実装をやっおみたしょう。
実装する䞊では、この資料に出おきおない Widget も必芁に応じお利甚する必芁がありたす。
ヒントは少なめにしおいたす。

タスクを削陀できるようにしよう

新しいタスクを远加できるようになりたしたが、間違っお入力したTodoを远加しおしたったずきなどに消せないのはちょっず䞍䟿ですね 。
ずいうこずで以䞋2぀の方法のどちらかで実装しおみおください。

䞭玚線: 削陀甚の×ボタンを蚭眮しお、タップしたら消えるようにしよう

䞊玚線: 画面の右から巊ぞスワむプした時に削陀できるようにしよう

6. おわり

お疲れ様でした
ひずたず、TODO リストが完成したした。しかし、動䜜ずしおはただただ必芁最䜎限です。
タスク䞀芧をアプリの状態ずしおしか保持しおいないので、アプリを再起動するずタスクが消えたす。
タスクの線集・削陀、期日の蚭定などなど、やれるこずはただただたくさん残っおいたす。

今回は特に觊れたせんでしたが、UIもあたりカスタマむズしおないたたなので、䞊蚘の内容ず合わせお調べおみたり䜜り蟌んでみたりしおくれるず嬉しいです。

今回の内容やカスタマむズで぀たづいたこずがあれば、メヌル(intern-info@jig.jp)かTwitter(https://twitter.com/jig_saiyo)のDMで聞いおくれれば䞀緒に考えたすので、お気軜に聞いおください

7. 解答

タスクを远加しおみようの解答を以䞋に瀺したす。

onSubmitted で入力されたテキスト v を content ずしお todoList に远加するずタスクを远加するこずができたす。
タスクの登録時、完了状態は絶察未完了であるはずなので、isFinish を false ずしお登録したしょう。
先ほどず同様に、状態の曎新時には setState を呌ぶこず

onSubmitted: (String v) {
  // 入力したテキストの送信時
  // 入力された文字をtodoに登録するプログラムを曞こう
  setState(() {
    todoList.add({'content': v, 'isFinish': false});
    _controller.clear();
  });
},