🦉
Flutterでルート定義をして画面遷移させたい
Flutterで画面遷移をさせる場合によくあるサンプルだとNavigator.push
を使ったものが多いですが、名前付きのルート定義をしてそれをもとに画面遷移させるパターンを学んだので書いておきます。
環境
- macOS Big Sur Version 11.3.1
- Flutter 2.2.0
- Dart 2.13.0
サンプル
- ルート定義
import 'package:first_flutter_app/align.dart';
import 'package:first_flutter_app/input_test.dart';
import 'package:first_flutter_app/safe_area_sample.dart';
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
Widget build(BuildContext context) {
return MaterialApp(
title: 'SafeArea Sample',
theme: ThemeData(
primaryColor: Colors.white,
),
routes: {
'/': (context) => SafeAreaSample(),
'/page1': (context) => AlignTestPage(),
'/page2': (context) => InputTest(),
},
);
}
}
- 定義したルートを使って遷移させる
import 'package:flutter/material.dart';
class SafeAreaSample extends StatelessWidget {
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('SafeAreaSample'),
),
body: SafeArea(
bottom: false,
child: Center(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
TextButton(
child: Text(
'Go to page1',
style: TextStyle(color: Colors.black),
),
style: TextButton.styleFrom(
backgroundColor: Colors.amber,
),
onPressed: () {
Navigator.pushNamed(context, '/page1');
},
),
SizedBox(
width: 10,
),
TextButton(
child: Text(
'Go to page2',
style: TextStyle(color: Colors.black),
),
style: TextButton.styleFrom(
backgroundColor: Colors.amber,
),
onPressed: () {
Navigator.pushNamed(context, '/page2');
},
),
],
),
),
),
);
}
}
MaterialApp
のroutes
にMap形式でルートを定義する
Mapを使ってキーにルート名、値に遷移させたいページをビルドする関数を登録します。
routes: {
'/': (context) => SafeAreaSample(),
'/page1': (context) => AlignTestPage(),
'/page2': (context) => InputTest(),
},
Navigator.pushNamed
を使って遷移させる
routes
を使って定義したページに遷移させるときは、Navigator.pushNamed
を使います。
Mapのキーを指定することで対応したページに遷移させることができます。
TextButton(
child: Text(
'Go to page1',
style: TextStyle(color: Colors.black),
),
style: TextButton.styleFrom(
backgroundColor: Colors.amber,
),
onPressed: () {
Navigator.pushNamed(context, '/page1');
},
),
実際に動かしてみる
感想とメリデメ
本記事の書き方でルート定義をした場合、main.dart
を見ればアプリにある全ページを一覧できるので開発時に全体を確認するときに役に立ちそうです。
逆にデメリットとしては、ルート名を変えたいときにコード全体で影響箇所を確認する必要があることくらいですかね?
とはいえ、const切っておいて使えばそこだけ変えればいいし、そもそもそこまで頻繁に変わるものでもないのでデメリットとしては小さい気がします。
むしろ、Navigator.push
とNavigator.pushNamed
が混ざっているほうがはるかにめんどくさそうです。このへんはプロジェクトでちゃんとルールを決めてどっちかに統一しておかないとページ遷移がカオスになって、あとになってめちゃくちゃ首を締めてきそうな気がします...。
と思っていたら、pushNamedにもデメリットがあるようで
こちらのブログでデメリットを解説されていました。
- ページの追加が面倒
- ページを表示するのに必須パラメータが何かを覚えていないといけない
- Navigatorを作った際に、onGenerateRouteで再定義しなければいけない
1.と2.はなるほどなーと理解できたのですが、まだBottomNavigationBar
を使ったことがないので3.については自分で試してみる必要がありそうです。
Discussion