Flutter: シンプルでStatelessなBottomNavigationBarを作ってみた話
このマガジンでは、自分の学習の記録として、シンプルなサンプルを作って解説しています。同じような入門者の方の役に立てば幸いです。
達成したいこと
今回はフッターにアイコンを並べて、押すと画面遷移するやつを取りあげます。Twitter やメルカリなど様々なアプリに使われていますよね。そいつをさくっと作ってみましょう。
出来上がりイメージ
こんな感じのものが作れます。
実装の方針
1. フッターにアイコンを並べるWidgetを調べる
2. アイコンをタップしたら指定したページに切り替える
1. フッターにアイコンを並べるWidgetを調べる
これは少し調べると BottomNavigationBar() で達成できそうなことがわかりました。アイコンをタップしたときの挙動は onTap で記述できるみたいです。
2. アイコンをタップしたら指定したページに切り替える
onTap: (index) {
// index にタップしたアイコンの番号が入っています。
// 左から 0, 1, 2, ... と並んでいるようです。
// indexをmodel側に渡して変更を通知。
// 更新された番号のページを読み込めば達成できそうですね。
model.currentIndex = index;
}
コメント部分に書いたような思考をして実装しました。
それではコード全体をみてみましょう。
まずはpageから。
// bottom_navigation_bar.dart
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:whiskit_app/presentation/bottom_navigation/bottom_navigation_model.dart';
class BottomNavigationPage extends StatelessWidget {
// 表示するページをリスト形式で宣言します
List<Widget> _pageList = <Widget>[
FirstPage(),
SecondPage(),
];
Widget build(BuildContext context) {
return MaterialApp(
// テーマはなんでも大丈夫です
theme: ThemeData(
brightness: Brightness.dark,
primaryColor: Colors.lightBlue[800],
accentColor: Colors.cyan[600],
textTheme: TextTheme(),
),
home: ChangeNotifierProvider<BottomNavigationModel>(
create: (_) => BottomNavigationModel(),
child:
Consumer<BottomNavigationModel>(builder: (context, model, child) {
return Scaffold(
// 今選択している番号のページを呼び出します。
body: _pageList[model.currentIndex],
bottomNavigationBar: BottomNavigationBar(
// 選択時の色やBarの色など設定できます。
backgroundColor: Colors.black54,
// 選択中のアイコンを更新しています。
currentIndex: model.currentIndex,
// ここからが肝です。
onTap: (index) {
// indexで今タップしたアイコンの番号にアクセスできます。
model.currentIndex =
index; // indexをモデルに渡したときに notifyListeners(); を呼んでいます。
},
items: [
// フッターアイコンの要素を並べています 最低2個以上必要みたいです。
BottomNavigationBarItem(
// アイコンとラベルは自由にカスタムしてください。
icon: Icon(Icons.face),
label: '',
),
BottomNavigationBarItem(
icon: Icon(Icons.fastfood),
label: '',
),
],
),
);
}),
),
);
}
}
// シンプルな画面構成のページを2つ用意しておきます。
// 本番では他のファイルで作り込んだページを指定して使っていくことになると思います。
class FirstPage extends StatelessWidget {
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Icon(
Icons.face,
size: 200,
)),
);
}
}
class SecondPage extends StatelessWidget {
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Icon(
Icons.fastfood,
size: 200,
)),
);
}
}
こちらはProviderです。
// bottom_navigation_model.dart
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
class BottomNavigationModel extends ChangeNotifier {
int _currentIndex = 0;
// getterとsetterを指定しています
// setのときにnotifyListeners()を呼ぶことアイコンタップと同時に画面を更新しています。
get currentIndex => _currentIndex;
set currentIndex(int index) {
_currentIndex = index;
notifyListeners(); // View側に変更を通知
}
}
今回は以上になります!
Statefulwidgetを使ったサンプルが多かったので、StatelessWidgetだけで構成してみました。 参考になれば幸いです!
最後まで読んでもらえて嬉しいです。よければフォローもお待ちしています。サポートは記事を書くときのコーヒーになります。