Flutter 学習 4: Flutter 開発の基礎 (3) ルーティング管理

目次

0 まえがき

1 ルーティング管理

 1.1 マテリアルページルート

1.2 ナビゲーター

 1.2.1 今後のプッシュ(BuildContextコンテキスト、Routeルート)

1.2.2 bool Pop(BuildContext context, [ result ])

1.2.3 将来の PushNamed(BuildContext context, String RouteName,{Object argument})

1.3 名前のないルート通過値

1.4 名前付きルーティング

 1.4.1 ルーティングテーブル

1.4.2 レジスタルーティングテーブル

1.4.3 ルーティング名を使用して新しいルーティング ページを開く

1.4.4 名前付きルートパラメータの受け渡し

1.4.5 名前のないルート値転送の適応 

1.5 ルート生成フック

1.6 概要


0 まえがき

この記事は、第 2 版 | 「Flutter in Practice · Second Edition」 (flutterchina.club)の序文の研究と要約です

1 ルーティング管理

  • 通常、ルートはモバイル開発におけるページを指します。これは、Web 開発における単一ページ アプリケーションのルートと同じ概念的意味を持ちます。
  • ルートは通常、Android ではアクティビティを指し、iOS では ViewController を指します。
  • いわゆるルーティング管理とは、ページ間の移動方法を管理するもので、通常はナビゲーション管理とも呼ばれます。
  • Flutter でのルーティング管理はネイティブ開発に似ています。Android であっても iOS であっても、ナビゲーション管理はルーティング スタックを維持します。ルーティング プッシュ操作は新しいページを開くことに対応し、ルーティング ポップ操作はページを閉じる操作に対応します。ルーティング管理主にルーティング スタックの管理方法を指します。

 1.1 マテリアルページルート

MaterialPageRoutePageRouteclassから継承されたPageRouteclass は、画面スペース全体を占めるモーダル ルーティング ページを表す抽象クラスであり、ルーティングの構築および切り替え中の遷移アニメーションに関連するインターフェイスとプロパティも定義します。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 概要

 実際の開発では、次のような利点がある名前付きルーティング管理を使用することをお勧めします。

  1. セマンティクスがより明確になります。
  2. コードは保守が容易です。匿名ルーティングを使用する場合は、Navigator.pushそれが呼び出される新しいルーティング ページを作成する必要があります。これには、新しいルーティング ページの dart ファイルをインポートする必要があるだけでなく、そのようなコードも非常に分散されます。
  3. onGenerateRouteグローバル ルーティング ジャンプの前処理ロジックを実行できます。

ルーティング MaterialApp には2 つのコールバック属性navigatorObserversもあります。onUnknownRoute

  • navigatorObserversすべてのルーティング ジャンプ アクションを監視できます
  • onUnknownRoute存在しない名前付きルートを開くときに呼び出されます

おすすめ

転載: blog.csdn.net/D_lunar/article/details/131416195