Flutterで画面遷移
Flutterにおける画面遷移の基本です。 以下の2通りの遷移方法があるようです。
- 直接画面を生成して遷移
- ルーティングを定義して名前で遷移
ここで紹介する方法は、iOS的にはNavigationスタイル(Push/Pop)の画面遷移になります。
概要
Navigator
クラスを使用します。
このクラスはRoute
オブジェクトをスタックとして管理するものです。
Flutterでは、一般的に画面だとかページだとか言われるものをRoute
と呼ぶそうです。
Navigator.push
もしくはNavigator.pushNamed
関数により遷移し、Navigator.pop
関数で前画面に戻ります。
画面の定義
まずは遷移用の画面を定義します。
遷移前の画面(FirstScreen)にRaisedButton
を2つ置き、タップ時にそれぞれのパターンで遷移をします。
遷移後の画面(SecondScreen)にはRaisedButton
を1つ置き、タップ時に前画面(FirstScreen)に戻ります。
class FirstScreen extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('First Screen'), ), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ RaisedButton( child: Text('Navigate directly'), onPressed: () { // 直接画面を生成して遷移 } ), RaisedButton( child: Text('Navigate with named route'), onPressed: () { // ルーティングを定義して名前で遷移 } ), ], ) ) ); } } class SecondScreen extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Second Screen'), ), body: Center( child: RaisedButton( child: Text('Go back!'), onPressed: () { // 前画面に戻る } ) ) ); } }
直接画面を生成して遷移
Navigator.push
関数を使用し、Route
を指定して遷移します。
Route
にはMaterialPageRoute
を指定しておけば、自動でプラットフォーム固有のトランジションアニメーションを実現してくれます。
(むしろ他のRouteをどうやって作るのかはまだ分かってません)
RaisedButton( child: Text('Navigate directly'), onPressed: () { Navigator.push( context, MaterialPageRoute(builder: (context) => SecondScreen()) ); } ),
ルーティングを定義して名前で遷移
MaterialApp
の初期化時にルーティングを定義し、
Navigator.pushNamed
関数を使用して遷移します。
- ルーティング定義
class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( ... // 初回起動画面を指定 initialRoute: '/', // ルーティングの定義 routes: { '/': (context) => FirstScreen(), '/second': (context) => SecondScreen(), }, ... ); } }
- 遷移処理
RaisedButton( child: Text('Navigate with named route'), onPressed: () { // ルーティングで定義した名前を指定して遷移 Navigator.pushNamed(context, "/second"); } ),
前画面に戻る
Navigator.pop
関数を使用します。
RaisedButton( child: Text('Go back!'), onPressed: () { Navigator.pop(context); } )
ちなみに、画面のWidgetにScaffold
を使用している場合はAppBarの左側に自動で戻るボタンが表示されるので、そちらから戻ることも出来ます。
ソース全体
- main.dart
import 'package:flutter/material.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', theme: ThemeData( primarySwatch: Colors.blue, ), initialRoute: '/', routes: { '/': (context) => FirstScreen(), '/second': (context) => SecondScreen(), }, ); } } class FirstScreen extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('First Screen'), ), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ RaisedButton( child: Text('Navigate directly'), onPressed: () { Navigator.push( context, MaterialPageRoute(builder: (context) => SecondScreen()) ); } ), RaisedButton( child: Text('Navigate with named route'), onPressed: () { Navigator.pushNamed(context, "/second"); } ), ], ) ) ); } } class SecondScreen extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Second Screen'), ), body: Center( child: RaisedButton( child: Text('Go back!'), onPressed: () { Navigator.pop(context); } ) ) ); } }