Flutterアプリ開発講座 UI基礎編 その9(ファイナル)

image

9|Todoアプリを仕上げよう

入力フォームを作る

一番下に入力フォームを作ります。入力フォームはTextFieldというウィジットで簡単に作れます。

ListViewTextFieldを縦並びにしたいのでこの二つをColumnに追加しましょう。
ここで便利機能の紹介です。
まず👇の画像の場所にカーソルを合わせて、
option + enterを押すと、 Rowに小さいContainer

選択肢が出てくるのでWrap with Columnをクリック。ListViewColumnの子になり、childrenの中の一つになりました。 これを「ListViewColumnでラップした」と言います。

child: Column(
children: [
ListView.builder( itemCount: todoList.length, itemBuilder: (context, index) { return ListTile( title: Text(todoList[index]), leading: Radio<bool?>( value: false, groupValue: null, onChanged: (bool? value) { clickDone(index); }, ), ); }, ),
],
),

Rowに小さいContainer

また、ListViewColumnの中で使うときは高さを指定してあげないといけないというルールがあります。 なので、ListViewExpandedでラップしましょう。操作は先ほどと同じです。 こうすることで、今回の場合残りの高さ全てがListViewに割り当てられ、高さが明確になります。

child: Column(
    children: [
Expanded(
child: ListView.builder( itemCount: todoList.length, itemBuilder: (context, index) { return ListTile( title: Text(todoList[index]), leading: Radio<bool?>( value: false, groupValue: null, onChanged: (bool? value) { clickDone(index); }, ), ); }, ),
),
], ),

ではColumnの中にTextFieldも追加しましょう。

 ),
SafeArea(
child: Padding(
padding:
const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
child: TextField(),
),
),
],

変更後: 画面下部にTextFieldができているはずです👇 Rowに小さいContainer

次にTextFieldの横に送信ボタンを作成します。今回ボタンはIconButtonを使って作成します。
TextFieldIconButtonを横並びにしたいのでまずはTextFieldRowでラップしましょう。

child: Row(
children: [
TextField(),
],
),

先ほどと同じで、Rowの中でTextFieldを使うときは横幅を設定してあげないといけないので、TextFieldをExpandedでラップしましょう。

child: Row(
    children: [
Expanded(
child: TextField(),
),
], ),

そうしたらRowIconButtonを追加しましょう。onPressedプロパティは一旦nullを入れておきます。

child: Row(
    children: [
      Expanded(
        child: TextField(),
      ),
IconButton(
icon: Icon(Icons.send),
color: Colors.blue,
onPressed: null,
)
], ),

変更後: TextFieldの右横に送信ボタンが表示されているはずです👇 Rowに小さいContainer

では送信ボタンがタップされた時に行いたい処理を関数にしてonPressedに設定しましょう。
今回はまず、todoList新しいTodoという文字列を追加する処理を書いてみましょう。画面の更新をするためにsetStateの中に書くことも忘れずに。

}

void sendTodo() {
setState(() {
todoList.add('新しいTodo');
});
}
void clickDone(int index) { ... }

そして今作った関数sendTodoonPressedプロパティに設定しましょう。

IconButton(
    icon: Icon(Icons.send),
    color: Colors.blue,
onPressed: sendTodo,
)

変更後: 送信ボタンをタップでリストに追加されるようになっているはずです👇
Rowに小さいContainer

TextFieldに入力された文字列をtodoListに保存したいです。そのために、TextFieldTextEditingControllerの管理下におきましょう。
まずTextEditingContollerをインスタンス化しましょう。

class _MyHomePageState extends State<MyHomePage> {
  List<String> todoList = ['ボールペンを買う', '本を読む', '電話をする'];
TextEditingController controller = TextEditingController();
Widget build(BuildContext context) { ... }

今インスタンス化したcontollerTextFieldcontrollerプロパティに設定しましょう。

Expanded(
child: TextField(controller: controller),
),

これでTextFieldcontrollerで管理することができるようになりました。
ではこれを使ってTextFieldに入力された文字列をリストに追加できるように処理を書き換えましょう。

void sendTodo() {
    setState(() {
todoList.add(controller.text);
controller.clear();
}); }

変更後: 👇完成!!!
Rowに小さいContainer

これにて完成です、お疲れ様でした。

問題

今は空の文字列でもリストに追加されてしまいます。
空の文字列Todoがリストに登録されないようにしてみてください。 Rowに小さいContainer