Flutterチュートリアルやってみた part2
環境
- 作業日: 2020/03/12
- OS: macOS Big Sur 11.2.1
- PC: MacBook Pro (13-inch, M1, 2020)
はじめに
前回に引き続きpart2をやっていきたいと思います。
part2では画面の遷移とテーマカラーの変更がテーマのようです!
前回までのコードは、こちらで!
https://github.com/tsuzukihashi/flutter-tutorial-part01
今回の作業ディレクトリは以下です。
https://github.com/tsuzukihashi/fulutter-tutorial-part02
step 0 migrate
最近Flutter2が発表されたので、チュートリアルでもmigrateについて記述がありました。
part01で行ったpubspec.yaml
を修正します。
null safety
に対応するためenglish_words
のバージョンをあげます。
english_words: ^4.0.0-0
pub get
した後に以下のコマンドを入力し、マイグレートします。
dart migrate --apply-changes
ここまでで一旦アプリを起動してListViewが表示されていることを確認します。
step 1 リストにアイコンを追加する
_RandomWordsState
に_saved
というSet
を追加します。
このSetにはユーザーがお気に入りした単語のペアが入ります。
SetはListと異なり、重複を許さず順番を保持し続けるという特性があります。
次に、_buildRowメソッドないにalreadySaved
チェックを追加して単語のペアがお気に入りに追加されているかしていないかを確認します。
次に_buildRow
にハートアイコンを追加します。
ListTile
のtrailing
にアイコンを追加します。
Widget _buildRow(WordPair pair) {
final alreadySaved = _saved.contains(pair);
return ListTile(
title: Text(
pair.asPascalCase,
style: _biggerFont,
),
trailing: Icon(
alreadySaved ? Icons.favorite : Icons.favorite_border,
color: alreadySaved ? Colors.red : null,
),
);
}
step 2 ハートアイコンをタップ可能にする
これを行うためには_buildRow
メソッドを更新します!
ListItem
のonTap
を実装します。
タイルがタップされたらsetState()
を呼び出し状態が通知されたことをフレームワークに伝える働きがあるそうです。
Widget _buildRow(WordPair pair) {
final alreadySaved = _saved.contains(pair);
return ListTile(
title: Text(
pair.asPascalCase,
style: _biggerFont,
),
trailing: Icon(
alreadySaved ? Icons.favorite : Icons.favorite_border,
color: alreadySaved ? Colors.red : null,
),
onTap: () {
setState(() {
if (alreadySaved) {
_saved.remove(pair);
} else {
_saved.add(pair);
}
});
},
);
step 3 新しい画面に遷移する
このステップではお気に入りを表示するためのページ(Flutterではページのことをルートと呼びます)を作ります。
ホームルートと新しいルートの間を移動する方法を学びます。
FlutterのNavigatorはアプリのルートを含むスタック管理します。
ルートをNavigatorのスタックにプッシュすると、そのルートが表示され、ルートをポップすると表示が前のルートの戻ります。
まず、遷移させるための要素として、AppBarにリストボタンを配置します。
_RandomWordsState
のbuild
メソッドのAppBar
にactions
を追加します。
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Startup Name Generator'),
actions: [IconButton(icon: Icon(Icons.list), onPressed: _onPressed)],
),
body: _buildSuggestions(),
);
}
}
また、IconButton
にはタップした際のメソッドが必要なため_onPressed
メソッドをState内に作っておきます。
void _onPressed() {}
この時点でボタンをタップしても何も起こりません。
ルートを作成し、Navigatorのスタックにプッシュする処理をかきます。
void _onPressed() {
Navigator.of(context)
.push(MaterialPageRoute<void>(builder: (BuildContext context) {
final tiles = _saved.map((WordPair pair) {
return ListTile(
title: Text(
pair.asPascalCase,
style: _biggerFont,
),
);
});
final divied =
ListTile.divideTiles(tiles: tiles, context: context).toList();
return Scaffold(
appBar: AppBar(
title: Text('Saved Suggestions'),
),
body: ListView(
children: divied,
),
);
}));
}
Navigator.of(context).push
でルートがスタックにプッシュされます。
次に、MaterialPageRoute
とそのビルダーを追加します。
ListViewを作るためにListTileを作成し、さらに仕切り線を追加しtoList()
でリストに変換しそれをListView
に食わせます。
アプリを再起動し、セルをタップしAppBarのリストアイコンをタップするとタップした単語のペアのリストを確認することができます。
また、何もしなくても戻るボタンができていることが確認することができます。
step 4 テーマを変更する
このステップではアプリのテーマを変更します。テーマを変更すると、外観と雰囲気を帰ることができます。
ThemeData
クラスを変更することで簡単にテーマを変更することができます。
以下のようにMyApp
クラスのthemeを変更してprimaryColorを白色に変更します。
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Startup Name Generator',
theme: ThemeData(primaryColor: Colors.white),
home: RandomWords(),
);
}
}
いろんな色を試してみたいときに、いちいちビルドし直さず、ホットリロードで反映されるためUIの変更を迅速に確認することができます。
以上で終わりです!