目次
1.2.1 今後のプッシュ(BuildContextコンテキスト、Routeルート)
1.2.2 bool Pop(BuildContext context, [ result ])
1.2.3 将来の PushNamed(BuildContext context, String RouteName,{Object argument})
1.4.3 ルーティング名を使用して新しいルーティング ページを開く
0 まえがき
この記事は、第 2 版 | 「Flutter in Practice · Second Edition」 (flutterchina.club)の序文の研究と要約です。
1 ルーティング管理
- 通常、ルートはモバイル開発におけるページを指します。これは、Web 開発における単一ページ アプリケーションのルートと同じ概念的意味を持ちます。
- ルートは通常、Android ではアクティビティを指し、iOS では ViewController を指します。
- いわゆるルーティング管理とは、ページ間の移動方法を管理するもので、通常はナビゲーション管理とも呼ばれます。
- Flutter でのルーティング管理はネイティブ開発に似ています。Android であっても iOS であっても、ナビゲーション管理はルーティング スタックを維持します。ルーティング プッシュ操作は新しいページを開くことに対応し、ルーティング ポップ操作はページを閉じる操作に対応します。ルーティング管理主にルーティング スタックの管理方法を指します。
1.1 マテリアルページルート
MaterialPageRoute
PageRoute
classから継承されたPageRoute
class は、画面スペース全体を占めるモーダル ルーティング ページを表す抽象クラスであり、ルーティングの構築および切り替え中の遷移アニメーションに関連するインターフェイスとプロパティも定義します。MaterialPageRoute
これは、マテリアル コンポーネント ライブラリによって提供されるルーティング コンポーネントであり、さまざまなプラットフォームのプラットフォーム ページ切り替えアニメーション スタイルと一致するルーティング切り替えアニメーションを実装できます。
- Android の場合、新しいページを開くと、新しいページは画面の下から画面の上にスライドし、ページを閉じると、現在のページは画面の上から下にスライドします。画面が消え、前のページが画面に表示されます。
- iOS の場合、ページが開かれると、新しいページがすべて画面に表示されるまで、新しいページが画面の右端から画面の左側にスライドし、前のページが現在の画面から左端にスライドします。ページを閉じるときはその逆で、現在のページが画面の右側からスライドアウトし、前のページが画面の左側からスライドインします。
- ルート切り替えアニメーションをカスタマイズしたい場合は、PageRouteを自分で継承して実装することができます。
MaterialPageRoute({
/*
用于构建路由页面的具体内容,返回值是一个新路由的widget实例。
*/
WidgetBuilder builder,
/*
包含路由的配置信息,如路由名称、是否初始路由(首页)。
*/
RouteSettings settings,
/*
是否维护原路由内存状态,默认true, 即当入栈一个新路由时,原来的路由仍然会被保存在内存中。
如果想在路由没用的时候释放其所占用的所有资源,可以设置maintainState为 false
*/
bool maintainState = true,
/*
表示新的路由页面是否是一个全屏的模态对话框,在 iOS 中,
如果fullscreenDialog为true,新页面将会从屏幕底部滑入(而不是水平方向)
*/
bool fullscreenDialog = false,
})
1.2 ナビゲーター
Navigator
これは、ルーティング ページを開いたり終了したりするためのメソッドを提供するルーティング管理コンポーネントです。Navigator
スタックは、アクティブなルートのセットを管理するために使用されます。- 通常、現在画面に表示されているページはスタックの一番上のルートです。
1.2.1 今後のプッシュ(BuildContextコンテキスト、Routeルート)
名前のないルート ページを開く: 指定されたルートをスタックにプッシュします (つまり、新しいページを開きます)。戻り値は、
Future
新しいルートがスタックからポップされる (つまり、閉じられる) ときに戻りデータを受け取るために使用されるオブジェクトです。
1.2.2 bool Pop(BuildContext context, [ result ])
ルーティング ページを閉じる: スタックから最上位のルートをポップします (つまり、現在画面に表示されているページを閉じます)。戻り値は bool オブジェクトです。
result
ページを閉じると、データは前のページに戻ります。
1.2.3 将来の PushNamed(BuildContext context, String RouteName,{Object argument})
名前付きルート ページを開く: 指定されたルートをスタックにプッシュします (つまり、新しいページを開きます)。戻り値は、
Future
新しいルートがスタックからポップされる (つまり、閉じられる) ときに戻りデータを受け取るために使用されるオブジェクトです。
1.3 名前のないルート通過値
/*
创建一个TipRoute路由,它接受一个提示文本参数,负责将传入它的文本显示在页面上,
另外TipRoute中添加一个“返回”按钮,点击后在返回上一个路由的同时会带上一个返回参数
*/
class TipRoute extends StatelessWidget {
TipRoute({
Key key,
required this.text, // 接收一个text参数
}) : super(key: key);
final String text;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("提示"),
),
body: Padding(
padding: EdgeInsets.all(18),
child: Center(
child: Column(
children: <Widget>[
Text(text),
ElevatedButton(
onPressed: () => Navigator.pop(context, "我是返回值"),
child: Text("返回"),
)
],
),
),
),
);
}
}
/*
打开新路由TipRoute的代码:
*/
class RouterTestRoute extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Center(
child: ElevatedButton(
onPressed: () async {
// 打开`TipRoute`,并等待返回结果
var result = await Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
return TipRoute(
// 路由参数
text: "我是提示xxxx",
);
},
),
);
//输出`TipRoute`路由返回结果
print("路由返回值: $result");
},
child: Text("打开提示页"),
),
);
}
}
1.4 名前付きルーティング
「Named Route」は名前が付いているルートです
1.4.1 ルーティングテーブル
名前付きルーティングを使用するには、最初にルーティング テーブル (ルーティング テーブル) を提供して登録し、どの名前がどのルーティング コンポーネントに対応するかをアプリケーションが認識できるようにする必要があります。
ルーティングテーブルの定義: マップです。
- key はルートの名前であり、文字列です。
- value は、対応するルーティング ウィジェットを生成するために使用されるビルダー コールバック関数です。
- ルート名を使用して新しいルートを開くと、アプリケーションはルート名に基づいてルーティング テーブル内で対応する WidgetBuilder コールバック関数を見つけ、そのコールバック関数を呼び出してルート ウィジェットを生成して返します。
Map<String, WidgetBuilder> routes;
1.4.2 レジスタルーティングテーブル
で
MaterialApp中
、routes
属性を追加し、ルーティング テーブルを登録します
MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
//注册路由表
routes:{
"new_page":(context) => NewRoute(),
... // 省略其他路由注册信息
} ,
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
/* 将home页面也注册为命名路由 */
MaterialApp(
title: 'Flutter Demo',
initialRoute:"/", //名为"/"的路由作为应用的home(首页)
theme: ThemeData(
primarySwatch: Colors.blue,
),
//注册路由表
routes:{
"new_page":(context) => NewRoute(),
"/":(context) => MyHomePage(title: 'Flutter Demo Home Page'), //注册首页路由
}
);
1.4.3 ルーティング名を使用して新しいルーティング ページを開く
onPressed: () {
//打开命名路由页面
Navigator.pushNamed(context, "new_page");
//打开非命名路由页面
//Navigator.push(context,
// MaterialPageRoute(builder: (context) {
// return NewRoute();
//}));
},
1.4.4 名前付きルートパラメータの受け渡し
/*
1.先注册一个路由:
*/
routes:{
"new_page":(context) => EchoRoute(),
} ,
/*
2.在路由页通过RouteSetting对象获取路由参数:
*/
class EchoRoute extends StatelessWidget {
@override
Widget build(BuildContext context) {
//获取路由参数
var args=ModalRoute.of(context).settings.arguments;
//...省略无关代码
}
}
/*
3.在打开路由时传递参数
*/
Navigator.of(context).pushNamed("new_page", arguments: "hi");
1.4.5 名前のないルート値転送の適応
1.3 値による名前のないルーティングでは、
TipRoute
パラメータtext
が受け入れられますが、TipRoute
ルーティング ページがルーティング テーブルに登録されている場合、TipRoute
ソース コードを変更せずにルーティング名で開き、パラメータの受け渡しを実装するにはどうすればよいですか?
/*
1.将TipRoute注册到路由表,同时传递text参数
*/
MaterialApp(
routes: {
"tip2": (context){
return TipRoute(text: ModalRoute.of(context)!.settings.arguments.toString());
},
},
);
/*
2.TipRoute源码,见【 1.3 非命名路由传值 】
*/
/*
3.在打开路由时传递参数值
*/
Navigator.of(context).pushNamed("tip2", arguments: "你好吗");
1.5 ルート生成フック
- ルート生成フックは、
MaterialApp
次のonGenerateRoute
プロパティを参照します。onGenerateRoute
名前付きルートにのみ有効ですonGenerateRoute
名前付きルートを開くときに呼び出すことができます。Navigator.pushNamed(...)
名前付きルートを開くために呼び出すとき、指定されたルート名がルーティング テーブルに登録されている場合は、ルーティング コンポーネントを生成するためにルーティング テーブル内の関数が呼び出されます。登録されていない場合は、ルーティング コンポーネントを生成するためにルーティング テーブル内の関数が呼び出されますbuilder
。ルーティングテーブルに登録されている場合、ルートを生成するために呼び出されますonGenerateRoute
。onGenerateRoute
ルーティングに関するより詳細な操作を実行したり、さまざまな状況に応じて別のページにジャンプしたりできます。許可制御も可能です。onGenerateRoute
適用可能なシナリオの例: 電子商取引アプリを開発するとします。ユーザーはログインしていなくても店舗、商品、その他の情報を表示できますが、取引記録、ショッピング カート、ユーザーの個人情報、その他のページはログに記録する必要があります。表示される前に。
MaterialApp(
... //省略无关代码
onGenerateRoute:(RouteSettings settings){
//返回一个Route<dynamic>
return MaterialPageRoute(builder: (context){
String routeName = settings.name;
/*
如果访问的路由页需要登录,但当前未登录,则直接返回登录页路由,引导用户登录;
其他情况则正常打开路由。
*/
}
);
}
);
1.6 概要
実際の開発では、次のような利点がある名前付きルーティング管理を使用することをお勧めします。
- セマンティクスがより明確になります。
- コードは保守が容易です。匿名ルーティングを使用する場合は、
Navigator.push
それが呼び出される新しいルーティング ページを作成する必要があります。これには、新しいルーティング ページの dart ファイルをインポートする必要があるだけでなく、そのようなコードも非常に分散されます。onGenerateRoute
グローバル ルーティング ジャンプの前処理ロジックを実行できます。ルーティング MaterialApp には2 つのコールバック属性
navigatorObservers
もあります。onUnknownRoute
navigatorObservers
すべてのルーティング ジャンプ アクションを監視できますonUnknownRoute
存在しない名前付きルートを開くときに呼び出されます