Contents
まとめ
(A)MaterialAppのroutesプロパティでルートテーブル指定+ModalRoute.ofで受け取る方法。
(B)MaterialAppのonGenerateRouteプロパティでルートテーブル指定+onGenerateRouteコールバック内で受け取り遷移先ウィジェットに渡す方法。
(1)遷移元からページ遷移するコード
=>(A)も(B)も全く同じ。
Navigator.pushNamed
メソッドを使う。
Navigator.pushNamed( context, ExtractArgumentsScreen.routeName, arguments: ScreenArguments( 'Extract Arguments Screen', 'This message is extracted in the build method.', ), );
(2)ルートテーブルの指定方法
=>(A) : MaterialAppのroutesプロパティで指定する。(受け取るのは遷移先ウィジェット内)
return MaterialApp( //... routes: { ExtractArgumentsScreen.routeName: (context) => ExtractArgumentsScreen(), }); );
=>(B) : MaterialAppのonGenerateRouteプロパティで指定する。
return MaterialApp( onGenerateRoute: (settings) { if (settings.name == PassArgumentsScreen.routeName) { final ScreenArguments args = settings.arguments; return MaterialPageRoute( builder: (context) { return PassArgumentsScreen( title: args.title, message: args.message, ); }, ); } //...
まずroutesプロパティのテーブルからルート名を探して、見つからない場合onGenerateRouteコールバックが呼び出される模様。
(3)遷移先での受け取り方法
=>(A) : 遷移先のウィジェット内でModalRoute.of(context).settings.argumetnsで受け取って使う。
@override Widget build(BuildContext context) { final ScreenArguments args = ModalRoute.of(context).settings.arguments; //...
=>(B) : 遷移先ウィジェット生成のコンストラクタのパラメータで渡して遷移先ウィジェット内で使う。
class PassArgumentsScreen extends StatelessWidget { static const routeName = '/passArguments'; final String title; final String message; //↓コンストラクタで受け取って各フィールドにセットする。 const PassArgumentsScreen({ Key key, @required this.title, @required this.message, }) : super(key: key);
Pass arguments to a named route
Navigatorは共通の識別子を使用して、アプリケーションの任意の部分から名前付きのルートに移動する能力を提供します。
場合によっては、名前付きルートに引数を渡す必要がある場合もあります。たとえば、/user
ルートに移動した時、ユーザーに関する情報をそのルートに渡したい場合があります。
このタスクは、Navigator.pushNamed()
メソッドのarguments
パラメーターを使用して実行できます 。
MaterialApp
またはCupertinoApp
コンストラクターに提供されるonGenerateRoute()
関数内で引数を抜き出します 。
このレシピは、名前付きルートに引数を渡し、ModalRoute.of()
とonGenerateRoute()
を使用して引数を読み取る方法を示します。
次の手順を使用して:
- 渡す必要のある引数を定義します。
- 引数を抜き出すウィジェットを作成します。
- ウィジェットを
routes
テーブルに登録します。 - 遷移先へページ遷移します。
1. Define the arguments you need to pass
まず、新しいrouteに渡す引数(arguments)を定義します。このサンプルでは、二つのデータ:スクリーンのtitleと、messageを渡します。
二つのデータを渡すために、この情報を格納するクラスを作成します。
//画面間で渡す引数は、どのようなオブジェクトでも渡せます。
//このサンプルではカスタマイズ可能なtitleとmessageを格納する
//クラスを定義します。
class ScreenArguments {
final String title;
final String message;
ScreenArguments(this.title, this.message);
}
2. Create a widget that extracts the arguments
遷移先ページであり、遷移元から受け取ったScreenArgumentsインスタンス(オブジェクト)からtitleとmessageを表示するウイジェット
ExtractArgumentsScreenクラス
を定義します。
遷移元から受け取ったScreenArgumentsにアクセスするには、ModalRoute.of()メソッドを使います。
このメソッドは、引数(遷移元から受け取るScreenArgumentsインスタンス)を含む現在のルートを返します。
// ModalRouteから必要なargumentsを抜き出す遷移先ウィジェット
class ExtractArgumentsScreen extends StatelessWidget {
static const routeName = '/extractArguments';
@override
Widget build(BuildContext context) {
// Extract the arguments from the current ModalRoute settings and cast
// them as ScreenArguments.
//現在のModalRouteのsettingsからargumentsを抜き出し、
//ScreenArguments型にキャストします。
final ScreenArguments args = ModalRoute.of(context).settings.arguments;
return Scaffold(
appBar: AppBar(
title: Text(args.title),
),
body: Center(
child: Text(args.message),
),
);
}
}
3. Register the widget in the routes
table
次に、MaterialAppウィジェットのroutesプロパティに
Map<String, Widget Function(BuildContext)>型
のテーブルを設定します。
routesプロパティは、「このルート名(文字列)が指定された時は、このウィジェットを生成してそのページに遷移する」という組み合わせを指定するものです。
MaterialApp(
routes: {
ExtractArgumentsScreen.routeName: (context) => ExtractArgumentsScreen(),
},
);
↑のroutesプロパティではルート名
ExtractArgumentsScreen.routeName (
‘/extractArguments’)
が指定された時は、
ExtractArgumentsScreen()
ウィジェットを生成してそのページに遷移しましょう、という指定。
最後に、ユーザーがボタンをタップした時に、Navigator.pushNamed()メソッドを呼び出して、ExtractArgumentsScreen
にページ遷移します。
Navigator.pushNamed()メソッドのargumentsプロパティに、ページ遷移時に受け渡したいオブジェクト(今回はScreenArgumentsインスタンス)を渡します。
そして遷移先のExtractArgumentsScreenにおいて、(ModalRouteを使って)引数(arguments)を抜き出し(受け取り)ます。
// A button that navigates to a named route. The named route
// extracts the arguments by itself.
//名前付きルートに遷移するためのボタン。遷移先ページで
//argumentsを抜き出す。
ElevatedButton(
child: Text("Navigate to screen that extracts arguments"),
onPressed: () {
// When the user taps the button, navigate to a named route
// and provide the arguments as an optional parameter.
//ユーザーがボタンをタップした時、名前付きルートに遷移し、
/ //オプショナルパラメータとしてargumentsを遷移先に受け渡す。
Navigator.pushNamed(
context,
ExtractArgumentsScreen.routeName,
arguments: ScreenArguments(
'Extract Arguments Screen',
'This message is extracted in the build method.',
),
);
},
),
Alternatively, extract the arguments using onGenerateRoute
ウィジェット内で直接引数を抽出する代わりに、onGenerateRoute()
関数内で引数を抜き出してウィジェットに渡すこともできます。
onGenerateRouteプロパティに設定されたコールバックは、引数として受け取ったRouteSettengsを基に正しいrouteを生成します。
MaterialApp(
// Provide a function to handle named routes. Use this function to
// identify the named route being pushed, and create the correct
// screen.
onGenerateRoute: (settings) {
// If you push the PassArguments route
if (settings.name == PassArgumentsScreen.routeName) {
// Cast the arguments to the correct type: ScreenArguments.
final ScreenArguments args = settings.arguments;
// Then, extract the required data from the arguments and
// pass the data to the correct screen.
return MaterialPageRoute(
builder: (context) {
return PassArgumentsScreen(
title: args.title,
message: args.message,
);
},
);
}
},
);
Interactive example
import 'package:flutter/material.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( //(2-B)ルートテーブル指定方法 onGenerateRoute: (settings) { if (settings.name == PassArgumentsScreen.routeName) { // Cast the arguments to the correct type: ScreenArguments. final ScreenArguments args = settings.arguments; //(3-B)↓argumentsの受け取り方法 return MaterialPageRoute( builder: (context) { return PassArgumentsScreen( title: args.title, message: args.message, ); }, ); } // The code only supports PassArgumentsScreen.routeName right now. // Other values need to be implemented if we add them. The assertion // here will help remind us of that higher up in the call stack, since // this assertion would otherwise fire somewhere in the framework. assert(false, 'Need to implement ${settings.name}'); return null; }, title: 'Navigation with Arguments', home: HomeScreen(), //(2-A)ルートテーブル指定方法 routes: { ExtractArgumentsScreen.routeName: (context) => ExtractArgumentsScreen(), }); } } class HomeScreen extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Home Screen'), ), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ // A button that navigates to a named route that. The named route // extracts the arguments by itself. ElevatedButton( child: Text("Navigate to screen that extracts arguments"), onPressed: () { //↓(1-A)ページ遷移コード Navigator.pushNamed( context, ExtractArgumentsScreen.routeName, arguments: ScreenArguments( 'Extract Arguments Screen', 'This message is extracted in the build method.', ), ); }, ), ElevatedButton( child: Text("Navigate to a named that accepts arguments"), onPressed: () { //↓(1-B)ページ遷移コード Navigator.pushNamed( context, PassArgumentsScreen.routeName, arguments: ScreenArguments( 'Accept Arguments Screen', 'This message is extracted in the onGenerateRoute function.', ), ); }, ), ], ), ), ); } } class ExtractArgumentsScreen extends StatelessWidget { static const routeName = '/extractArguments'; @override Widget build(BuildContext context) { //↓(3-A)argumntsの受け取り方法 final ScreenArguments args = ModalRoute.of(context).settings.arguments; return Scaffold( appBar: AppBar( title: Text(args.title), ), body: Center( child: Text(args.message), ), ); } } class PassArgumentsScreen extends StatelessWidget { static const routeName = '/passArguments'; final String title; final String message; const PassArgumentsScreen({ Key key, @required this.title, @required this.message, }) : super(key: key); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text(title), ), body: Center( child: Text(message), ), ); } } class ScreenArguments { final String title; final String message; ScreenArguments(this.title, this.message); }
参考
https://flutter.dev/docs/cookbook/navigation/navigate-with-arguments