Chapter 04

Hands-on 1

takumma
takumma
2021.09.13に更新

ヘッダーのタイトルを変更

まずはヘッダーのタイトルを変更してみましょう。
MyApp クラスを以下のように変更します。

main.dart
- home: const MyHomePage(title: 'Flutter Demo Home Page'),
+ home: const MyHomePage(title: 'Flutter TODO App'),

変更したら、ホットリロードをしましょう。Android Studio なら Ctrl + S(Mac なら Command + S) でホットリロードができます。

するとヘッダーのタイトルが変更されます。

テーマを変更

次はアプリのテーマを変更してみましょう。
MyApp クラスを以下のように変更します。指定する色は好きに変更して構いません。
(参考:MaterialColor)

main.dart
  theme: ThemeData(
-   primarySwatch: Colors.blue,
+   primarySwatch: Colors.red,
    visualDensity: VisualDensity.adaptivePlatformDensity,
),

ホットリロードして確認すると、ヘッダーと右下のボタンの色が変更されます。

MyHomePage クラスを移動

MyHomePage クラスと _MyHomePageState クラスを別のファイルに移動させます。
main,dart と同じディレクトリ(lib/)に my_home_page.dart ファイルを作って、そこに MyHomePage と _MyHomePageState を移動させます。

my_home_page.dart
import 'package:flutter/material.dart'; //インポートは忘れずに

class MyHomePage extends StatefulWidget {
  // 略
}

class _MyHomePageState extends State<MyHomePage> {
  // 略
}

main.dart では、MyHomePage と _MyHomePageState を削除して、代わりに my_home_page.dart ファイルをインポートします。

main.dart
  import 'package:flutter/material.dart';

+ import 'my_home_page.dart';

  // 略

- class MyHomePage extends StatefulWidget {
-   // 略
- }
- 
- class _MyHomePageState extends State<MyHomePage> {
-   // 略
- }

ホットリロードしても、コードを移動させただけなので動作は変わりません。

リストの表示

まずはリストを表示してみましょう。
リストは ListViewListTile で表現できます。
MyHomePageState を以下のように変更してみてください。ちなみに、Card はマテリアルデザインのカードの Widget です。

my_home_page.dart
  class _MyHomePageState extends State<MyHomePage> {

    // 略

    
    Widget build(BuildContext context) {
      return Scaffold(
        appBar: AppBar(
          title: Text(widget.title),
        ),
-       body: Center(
-         child: Column(
-           mainAxisAlignment: MainAxisAlignment.center,
-           children: <Widget>[
-             const Text(
-               'You have pushed the button this many times:',
-             ),
-             Text(
-               '$_counter',
-               style: Theme.of(context).textTheme.headline4,
-             ),
-           ],
-         ),
-       ),
+       body: ListView(
+         children: const [
+           Card(
+             child: ListTile(
+               title: Text("サンプルテキスト1"),
+             ),
+           ),
+           Card(
+             child: ListTile(
+               title: Text("サンプルテキスト2"),
+             ),
+           ),
+           Card(
+             child: ListTile(
+               title: Text("サンプルテキスト3"),
+             ),
+           ),
+         ],
+       ),
        floatingActionButton: FloatingActionButton(
          onPressed: _incrementCounter,
          tooltip: 'Increment',
          child: const Icon(Icons.add),
        ),
      );
    }
  }

すると、サンプルテキストの書かれたカードがリストになります。

ListView.builder()

先ほどの Card(...) の数を増やすと、カードも増えます。しかし、同じようなコードを何度も書くのは面倒です。また、今回は後でこのリストの要素を増やしたり減らしたりするので、この書き方では困ってしまいます。
そこで、ListView.builder を使ってみましょう。
先ほどのコードを以下のように変更してください。

my_home_page.dart
- body: ListView(
-   children: const [
-     Card(
-       child: ListTile(
-         title: Text("サンプルテキスト1"),
-       ),
-     ),
-     Card(
-       child: ListTile(
-         title: Text("サンプルテキスト1"),
-       ),
-     ),
-     Card(
-       child: ListTile(
-         title: Text("サンプルテキスト1"),
-       ),
-     ),
-   ]
- ), 
+ body:ListView.builder(
+   itemCount: 3,
+   itemBuilder: (BuildContext context, int index) {
+     return const Card(
+       child: ListTile(
+         title: Text("サンプルテキスト"),
+       ),
+     );
+   },
+ ),

確認すると、先ほどと同じようにサンプルテキストの書かれたカードがリストになります。

では、itemCount を 3 から 4 に変更して確認してみましょう。
するとカードの数も 4 つになります。
このように、ListView.builder() の itemCount にはリストのアイテムの数を指定します。
そして itemBuilder はリストのアイテムを表すウィジェットツリーを指定します。

このままだと同じテキストのカードが何枚も表示されるだけなので、それぞれ違う文字を表示できるようにしてみましょう。
まず、_MyHomePageState に文字列の配列を追加します。

my_home_page.dart
  class _MyHomePageState extends State<MyHomePage> {
+   final List<String> _todoItems = [
+     "英語の課題",
+     "牛乳を買う",
+   ];

そして ListView.builder
itemCount には _todoItems.lengthlength は配列の長さを表すプロパティ)を、
itemBuilder のテキストには、 _todoItems[index] を指定します。

my_home_page.dart
  body:ListView.builder(
-   itemCount: 3,
+   itemCount: _todoItems.length,
    itemBuilder: (BuildContext context, int index) {
-     return const Card(
+     return Card(
        child: ListTile(
-         title: Text("サンプルテキスト"),
+         title: Text(_todoItems[index]),
        ),
      );
    },
  ),

_todoItems の文字列がカードに反映されます。

リストの UI を更新

リストの表示ができたので、リストの UI を少し変更してみましょう。
今回はカードに枠線を追加して、leading アイコン(リストの右側のアイコン)を追加します。
leading アイコンはハンズオンの後半で活用します。

my_home_page.dart
  body:ListView.builder(
    itemCount: _todoItems.length,
    itemBuilder: (BuildContext context, int index) {
      return Card(
-       child: ListTile(
-         title: Text(_todoItems[index]),
-       ),
+       child: Container(
+         decoration: const BoxDecoration(
+           border: Border.all(width: 1.0, color: Colors.red),
+         ),
+         child: ListTile(
+           title: Text(_todoItems[index]),
+           trailing: IconButton(
+             icon: const Icon(Icons.more_vert),
+             onPressed: () {},
+           ),
+         ),
+       ),
      );
    },
  ),

これで UI を更新できました。

次のチャプターでは、リストを追加できるように実装していきます!