Flutter入門(18):Flutter 組件之 Route 詳解

1. 基本介紹

Route 在 Flutter 里是極其重要的部分性锭,用來(lái)處理頁(yè)面跳轉(zhuǎn)京痢。本文主要普通路由,命名路由篷店,以及自定義路由等。
如果是簡(jiǎn)單的頁(yè)面跳轉(zhuǎn)可以參考Flutter 頁(yè)面創(chuàng)建與跳轉(zhuǎn)臭家。

2. 示例代碼

代碼下載地址疲陕。如果對(duì)你有幫助的話記得給個(gè)關(guān)注,代碼會(huì)根據(jù)我的 Flutter 專題不斷更新钉赁。

3. 基礎(chǔ)功能

  • 命名路由 routes
  • 路由跳轉(zhuǎn) push蹄殃、pop
  • 初始路由 initialRoute
  • 路由攔截 onGenerateRoute

4. 命名 Route 詳解

4.1 容器創(chuàng)建

優(yōu)雅的編程,我們創(chuàng)建一個(gè) materialapp.dart 文件你踩。

import 'package:flutter/material.dart';

class FMMaterialAppVC extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return MaterialApp(
      home: Scaffold(
        body: AAA(),
      ),
      routes: {
        '/bbb': (context) => BBB(),
        '/ccc': (context) => CCC(),
        '/ddd': (context) => DDD(),
      },
    );
  }
}

class AAA extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      appBar: AppBar(
        title: Text('AAA'),
      ),
      body: Center(
        child: RaisedButton(
          child: Text('點(diǎn)擊前往BBB'),
          onPressed: (){
            Navigator.pushNamed(context, '/bbb');
          },
        ),
      ),
    );
  }
}

class BBB extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      appBar: AppBar(
        title: Text('BBB'),
      ),
      body: Center(
        child: RaisedButton(
          child: Text('點(diǎn)擊前往CCC'),
          onPressed: (){
            Navigator.pushNamed(context, '/ccc');
          },
        ),
      ),
    );
  }
}

class CCC extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      appBar: AppBar(
        title: Text('CCC'),
      ),
      body: Center(
        child: RaisedButton(
          child: Text('點(diǎn)擊前往DDD'),
          onPressed: (){
            Navigator.pushNamed(context, '/ddd');
          },
        ),
      ),
    );
  }
}

class DDD extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      appBar: AppBar(
        title: Text('DDD'),
      ),
      body: Center(
        child: RaisedButton(
          child: Text('點(diǎn)擊回到AAA'),
          onPressed: (){
            Navigator.popUntil(context, (route) => route.isFirst);
          },
        ),
      ),
    );
  }
}

我們?yōu)?BBB诅岩,CCC,DDD 進(jìn)行了命名带膜,效果如下吩谦。


named route.gif

4.2 路由跳轉(zhuǎn)方式之 Push 詳解

在上文中,我們使用了 pushNamed 方法膝藕,推到一個(gè)新的頁(yè)面式廷。

class AAA extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      appBar: AppBar(
        title: Text('AAA'),
      ),
      body: Center(
        child: RaisedButton(
          child: Text('點(diǎn)擊前往BBB'),
          onPressed: (){
            Navigator.pushNamed(context, '/bbb');
          },
        ),
      ),
    );
  }
}

路由 push 其實(shí)還有很多種寫法。

4.2.1 Navigator.pushNamed

無(wú)參數(shù)

Navigator.pushNamed(context, '/bbb');

有參數(shù)

final datas = {"data": ["1","2","3"]};
Navigator.pushNamed(context, '/bbb', arguments: datas);

4.2.2 Navigator.push

無(wú)參數(shù)

            Navigator.push(
                context,
                MaterialPageRoute(
                  builder: (context){
                      return BBB();
                  }
            );

有參數(shù)芭挽,name 可以用來(lái)給路由命名滑废,arguments 用來(lái)傳遞參數(shù)

            final datas = {"data": ["1","2","3"]};

            Navigator.push(
                context,
                MaterialPageRoute(
                  builder: (context){
                      return BBB();
                  },
                  settings: RouteSettings(
                    name: '/bbb',
                    arguments: datas,
                  ),
                ),
            );

上面代碼意思就是跳轉(zhuǎn)到 BBB() 頁(yè)面蝗肪,并且給 BBB() 命名為 '/bbb',在路由堆棧中蠕趁,讀取到這個(gè) route 時(shí)薛闪,route.setting.name 與該命名相同。

4.2.3 Navigator.of(context).pushNamed

無(wú)參數(shù)

            Navigator.of(context).pushNamed('/bbb');

有參數(shù)

            final datas = {"data": ["1","2","3"]};
            Navigator.of(context).pushNamed('/bbb',arguments: datas);

4.2.4 Navigator.of(context).push

無(wú)參數(shù)

            Navigator.of(context).push(
              MaterialPageRoute(
                builder: (context){
                  return BBB();
                }
              ),
            );

有參數(shù)

            final datas = {"data": ["1","2","3"]};

            Navigator.of(context).push(
              MaterialPageRoute(
                builder: (context){
                  return BBB();
                },
                settings: RouteSettings(
                  name: '/bbb',
                  arguments: datas,
                ),
              ),
            );

4.3 路由跳轉(zhuǎn)方式之 Push 進(jìn)階

4.2 中是最為常用的頁(yè)面進(jìn)出棧俺陋,但是在某些場(chǎng)合需要有特殊的處理豁延。
注意:寫法大同小異,后續(xù)就不在贅述傳參方式倔韭,均與4.2相同术浪。

4.3.1 pushNamedAndRemoveUntil

例如我們頁(yè)面從AAA->BBB->CCC->DDD,這樣進(jìn)行頁(yè)面寿酌,但是我們希望 CCC 再使用過(guò)后就被銷毀胰苏。使得頁(yè)面層級(jí)變?yōu)?AAA-BBB-DDD。

  • Navigator.pushNamedAndRemoveUntil

如下方代碼醇疼,我們?cè)?CCC 中來(lái)做處理硕并。
我們的頁(yè)面層級(jí)為 AAA->BBB->CCC->DDD,我們?cè)?CCC 中 push 到 DDD 頁(yè)面秧荆,然后從棧頂開(kāi)始刪除倔毙,直到這個(gè)route.setting.name == '/bbb',也就是銷毀 BBB 與 DDD 中間所有的頁(yè)面乙濒。

class CCC extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      appBar: AppBar(
        title: Text('CCC'),
      ),
      body: _listView(context),
    );
  }
  
  ListView _listView(BuildContext context){
    return ListView(
      children: [
        ListTile(
          title: Text("Navigator.pushNamed"),
          onTap: (){
            Navigator.pushNamed(context, '/ddd');
          },
        ),
        ListTile(
          title: Text("Navigator.pushNamedAndRemoveUntil"),
          onTap: (){
            Navigator.pushNamed(context, '/ddd');
          },
        ),
        ListTile(
          title: Text("Navigator.of(context).pushNamedAndRemoveUntil"),
          onTap: (){
            Navigator.of(context).pushNamedAndRemoveUntil('/ddd', (route) => route.settings.name == '/ddd');
          },
        ),
        ListTile(
          title: Text("Navigator.pushNamedAndRemoveUntil - current"),
          onTap: (){
            Navigator.of(context).pushNamedAndRemoveUntil('/ddd', (route) => route.isCurrent);
          },
        ),
        ListTile(
          title: Text("Navigator.pushReplacementNamed"),
          onTap: (){
            Navigator.pushReplacementNamed(context, '/ddd');
          },
        ),
        ListTile(
          title: Text("Navigator.of(context).pushReplacementNamed"),
          onTap: (){
            Navigator.of(context).pushReplacementNamed('/ddd');
          },
        ),
        ListTile(
          title: Text("Navigator.pushReplacement"),
          onTap: (){
            Navigator.pushReplacement(context,
              MaterialPageRoute(
                builder: (context){
                  return DDD();
                },
                settings: RouteSettings(
                  name: '/ddd',
                ),
              ),
            );
          },
        ),
        ListTile(
          title: Text("Navigator.of(context).pushReplacement"),
          onTap: (){
            Navigator.of(context).pushReplacement(
              MaterialPageRoute(
                builder: (context){
                  return DDD();
                },
                settings: RouteSettings(
                  name: '/ddd',
                ),
              ),
            );
          },
        ),
        ListTile(
          title: Text("Navigator.popAndPushNamed"),
          onTap: (){
            Navigator.popAndPushNamed(context, '/ddd');
          },
        ),
        ListTile(
          title: Text("Navigator.of(context).popAndPushNamed"),
          onTap: (){
            Navigator.of(context).popAndPushNamed('/ddd');
          },
        ),
      ],
    );
  }
}

如gif圖陕赃,我們push 順序?yàn)?AAA->BBB->CCC->DDD,返回時(shí)為 DDD->BBB->AAA颁股,CCC頁(yè)面銷毀么库。


route removeUnti.gif
  • Navigator.of(context).pushNamedAndRemoveUntil
            Navigator.of(context).pushNamedAndRemoveUntil('/ddd', (route) => route.settings.name == '/bbb');
route removeUnti.gif
  • Navigator.of(context).pushNamedAndRemoveUntil('/ddd', (route) => route.isCurrent)
    跳轉(zhuǎn)到指定頁(yè)面,并刪除前邊所有頁(yè)面
Navigator.of(context).pushNamedAndRemoveUntil('/ddd', (route) => route.isCurrent)
// 等價(jià)于下面這行代碼
            //Navigator.of(context).pushNamedAndRemoveUntil('/ddd', (route) => route.settings.name == '/ddd');
route removeUntil current.gif

4.3.2 pushReplacementNamed

例如我們頁(yè)面從AAA->BBB->CCC->DDD甘有,這樣進(jìn)行頁(yè)面诉儒,但是我們希望 CCC 再使用過(guò)后就被銷毀。使得頁(yè)面層級(jí)變?yōu)?AAA-BBB-DDD亏掀。

注意:同4.2.2區(qū)別忱反,假設(shè)我們的頁(yè)面為 AAA->BBB->CCC->DDD->EEE->FFF,我們?cè)?EEE 頁(yè)面跳轉(zhuǎn)到 FFF 并且 removeUntil('/bbb')滤愕,那么我們的頁(yè)面層級(jí)則會(huì)變成 AAA->BBB->FFF温算。而使用 pushReplacementNamed('/ddd'),則會(huì)變成 AAA->BBB->CCC->DDD->FFF该互。

  • Navigator.pushReplacementNamed
            Navigator.pushReplacementNamed(context, '/ddd');
route pushReplacement.gif
  •         Navigator.of(context).pushReplacementNamed
    
            Navigator.of(context).pushReplacementNamed('/ddd');
  • Navigator.pushReplacement

具體可以參考 4.2 寫法

            Navigator.pushReplacement(context,
                  MaterialPageRoute(
                    builder: (context){
                      return DDD();
                    },
                    settings: RouteSettings(
                      name: '/ddd',
                    ),
                  ),
            );
  • Navigator.of(context).pushReplacement
    具體可以參考 4.2 寫法
            Navigator.of(context).pushReplacement(
              MaterialPageRoute(
                builder: (context){
                  return DDD();
                },
                settings: RouteSettings(
                  name: '/ddd',
                ),
              ),
            );

4.3.3 popAndPushNamed

先 pop 一級(jí)米者,然后在 push 到對(duì)應(yīng)頁(yè)面,效果與4.3.2 相同

  • Navigator.popAndPushNamed
            Navigator.popAndPushNamed(context, '/ddd');
route popAndPushNamed.gif
  • Navigator.of(context).popAndPushNamed
            Navigator.of(context).popAndPushNamed('/ddd');

4.4 路由跳轉(zhuǎn)方式之 Pop 詳解

Pop 是路由返回方式,與 push 正好相反蔓搞,push 用來(lái)控制頁(yè)面入棧胰丁,而 pop 則控制頁(yè)面出棧。其實(shí)左上角的返回按鈕會(huì)默認(rèn)執(zhí)行一次 pop 方法喂分。

由于 pop 是返回方式锦庸,我們?cè)谧詈笠粋€(gè)頁(yè)面 DDD 中操作。

class DDD extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      appBar: AppBar(
        title: Text('DDD'),
      ),
      body: _listView(context),
    );
  }

  ListView _listView(BuildContext context){
    return ListView(
      children: [
        ListTile(
          title: Text('Navigator.pop'),
          onTap: (){
            Navigator.pop(context);
            // final data = {"data":["1","2","3"]};
            // Navigator.pop(context, data);
          },
        ),
        ListTile(
          title: Text('Navigator.pop'),
          onTap: (){
            Navigator.of(context).pop();
          },
        ),
        ListTile(
          title: Text('Navigator.canPop'),
          onTap: (){
            bool canpop = Navigator.canPop(context);
            if (canpop) Navigator.pop(context);
          },
        ),
        ListTile(
          title: Text('Navigator.maybePop'),
          onTap: (){
            Navigator.maybePop(context);
          },
        ),
      ],
    );
  }
}
route pop.gif

4.4.1 Navigator.pop

無(wú)參數(shù)

            Navigator.pop(context);

有參數(shù)

            final data = {"data":["1","2","3"]};
            Navigator.pop(context, data);

4.4.2 Navigator.of(context).pop

無(wú)參數(shù)

            Navigator.of(context).pop();

有參數(shù)

            final data = {"data":["1","2","3"]};
            Navigator.of(context).pop(data);

4.4.3 Navigator.canPop

判斷是否可以 pop

            bool canpop = Navigator.canPop(context);
            if (canpop) Navigator.pop(context);

4.4.4 Navigator.of(context).canPop

            bool canpop = Navigator.of(context).canPop();

4.4.5 Navigator.maybePop

先判斷是否可以 pop蒲祈,如果可以甘萧,在pop,相當(dāng)于 4.4.3 中代碼

            Navigator.maybePop(context);

4.4.6 Navigator.of(context).maybePop

            Navigator.of(context).maybePop(context);

4.5 路由跳轉(zhuǎn)方式之 Pop 進(jìn)階

4.4 中是最為常用的頁(yè)面進(jìn)出棧梆掸,但是在某些場(chǎng)合需要有特殊的處理扬卷。pop 進(jìn)階方法比較少,只有 popUntil 與 popAndPushNamed 酸钦,在4.3.3中講過(guò)后者了怪得,這里不重復(fù)敘述。

  • 回到棧頂
            Navigator.popUntil(context, (route) => route.isFirst);
  • 回到指定頁(yè)面

我們使用下方代碼回到 BBB 頁(yè)面

            Navigator.popUntil(context, (route) => route.settings.name == '/bbb');
  • 頁(yè)面堆棧了解
    這里我們自定義一下方法卑硫,查看一下當(dāng)前堆棧的所有 route
            Navigator.popUntil(context, (route) => _lookRoutes(route));
  bool _lookRoutes(Route route){
    print(route);
    return route.isFirst;
  }
all routes.png

我們來(lái)看一下上述頁(yè)面的所有效果徒恋。


route popUntil.gif

5. 初始路由 initialRoute

我們注釋掉 home 屬性,使用 initialRoute 來(lái)加載頁(yè)面

  Widget build(BuildContext context) {
    // TODO: implement build
    return MaterialApp(
      // home: Scaffold(
      //   body: AAA(),
      // ),
      initialRoute: '/ccc',
      routes: {
        '/aaa': (context) => AAA(),
        '/bbb': (context) => BBB(),
        '/ccc': (context) => CCC(),
        '/ddd': (context) => DDD(),
      },
    );
  }
initialRoute ccc.png

5.1 initialRoute 使用了未命名的路由

報(bào)錯(cuò)如下欢伏。

A GlobalKey was used multiple times inside one widget's child list.

注意:initialRoute 需要使用 routes 表中的命名過(guò)的路由入挣,否則會(huì)報(bào)錯(cuò)。

5.2 解決方案

  • a. 更改 initialRoute 為 routes 表里命名過(guò)得路由。

  • b. 設(shè)置根路由
    設(shè)置路由 '/' ,當(dāng)初始路由異常時(shí),會(huì)停留在根路由。

  Widget build(BuildContext context) {
    // TODO: implement build
    return MaterialApp(
      // home: Scaffold(
      //   body: AAA(),
      // ),
      initialRoute: '/ccc',
      routes: {
        '/': (context) => AAA(),
        '/bbb': (context) => BBB(),
        '/ccc': (context) => CCC(),
        '/ddd': (context) => DDD(),
      },
    );
  }
initialRoute plan1.png
  • c. 使用未知路由
  Widget build(BuildContext context) {
    // TODO: implement build
    return MaterialApp(
      // home: Scaffold(
      //   body: AAA(),
      // ),
      initialRoute: '/cc',
      routes: {
        '/aaa': (context) => AAA(),
        '/bbb': (context) => BBB(),
        '/ccc': (context) => CCC(),
        '/ddd': (context) => DDD(),
      },
      onUnknownRoute: (setting){
        print(setting);
        return MaterialPageRoute(builder: (context) => AAA());
      },
    );
  }
initialRoute plan2.png

6. 未知路由 onUnknownRoute

class FMMaterialAppVC extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return MaterialApp(
      initialRoute: '/',
      routes: {
        '/': (context) => AAA(),
        '/bbb': (context) => BBB(),
        '/ccc': (context) => CCC(),
        '/ddd': (context) => DDD(),
      },
      onUnknownRoute: (setting){
        print(setting);
        return MaterialPageRoute(builder: (context) => AAA());
      },
    );
  }
}

class BBB extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      appBar: AppBar(
        title: Text('BBB'),
      ),
      body: Center(
        child: RaisedButton(
          child: Text('點(diǎn)擊前往CCC'),
          onPressed: (){
            Navigator.pushNamed(context, '/cc');
          },
        ),
      ),
    );
  }
}

我們?cè)?BBB 頁(yè)面中 push 一個(gè)錯(cuò)誤的 '/cc' 路由噪馏,按照我們 onUnknownRoute 中的設(shè)置,我們返回一個(gè) AAA(),用這個(gè)可以做一個(gè)統(tǒng)一的報(bào)錯(cuò)頁(yè)面佳吞。


route onUnknownRoute.gif

7. 路由攔截 onGenerateRoute

class FMMaterialAppVC extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return MaterialApp(
      // home: Scaffold(
      //   body: AAA(),
      // ),
      initialRoute: '/',
      routes: {
        '/': (context) => AAA(),
        '/bbb': (context) => BBB(),
        '/ccc': (context) => CCC(),
        '/ddd': (context) => DDD(),
      },
      // onGenerateInitialRoutes: (string){
      //   return [
      //     MaterialPageRoute(builder: (context) => AAA()),
      //   ];
      // },
      onGenerateRoute: (setting){
        print(setting);
        return MaterialPageRoute(builder: (context) => CCC());
      },
      onUnknownRoute: (setting){
        print(setting);
        return MaterialPageRoute(builder: (context) => AAA());
      },
    );
  }
}

應(yīng)該有很多小伙伴跟我一樣,onGenerateRoute 不執(zhí)行魔眨,明明寫了 onGenerateRoute 方法媳维,但是卻不響應(yīng)。查了挺多博客遏暴,沒(méi)有相關(guān)描述侄刽,然后去翻了官方文檔和源碼,終于找到問(wèn)題朋凉。

onGenerateRoute 路由攔截不能與命名路由一起使用州丹,否則會(huì)只執(zhí)行命名路由,不在進(jìn)行攔截。下面我們注釋掉命名路由墓毒,然后通過(guò)路由攔截吓揪,自定義一套路由跳轉(zhuǎn),從而實(shí)現(xiàn)命名路由的功能所计。

  Widget build(BuildContext context) {
    // TODO: implement build
    return MaterialApp(
      initialRoute: '/',
      // routes: {
      //   '/': (context) => AAA(),
      //   '/bbb': (context) => BBB(),
      //   '/ccc': (context) => CCC(),
      //   '/ddd': (context) => DDD(),
      // },
      // onGenerateInitialRoutes: (string){
      //   return [
      //     MaterialPageRoute(builder: (context) => AAA()),
      //   ];
      // },
      onGenerateRoute: (setting){
        print(setting);
        final isLogin = true;
        
        final routes = {
          '/': (context) => AAA(),
          '/bbb': (context) => BBB(),
          '/ccc': (context) => CCC(),
          '/ddd': (context) => DDD(),
        };
        
        if (!isLogin) {
           return MaterialPageRoute(builder: (context) => AAA());
        }
        
        return MaterialPageRoute(builder: routes[setting.name], settings: setting);
      },
      onUnknownRoute: (setting){
        print(setting);
        return MaterialPageRoute(builder: (context) => AAA());
      },
    );
  }

舉一反三柠辞,在攔截路由中自定義一張路由表。當(dāng)未登錄時(shí)主胧,對(duì)頁(yè)面進(jìn)行攔截叭首,跳轉(zhuǎn)到登錄頁(yè)面,已登錄時(shí)踪栋,正常加載路由表內(nèi)的頁(yè)面焙格,實(shí)現(xiàn)路由攔截功能。


route onGenerateRoute.gif

8. 路由傳值

在App中夷都,頁(yè)面之間的通訊和傳值是非常重要的眷唉,這里只單獨(dú)介紹一下使用路由時(shí)的傳值方式,以及反向傳值的方法损肛。

我們?cè)?BBB 頁(yè)面使用 pushNamed 傳值給 CCC厢破,在 CCC 頁(yè)面介紹如何接收路由傳值。然后在 CCC 頁(yè)面使用 pop 帶參數(shù)回來(lái)治拿,在 BBB 頁(yè)面介紹如何接收路由反參摩泪。

8.1 路由正向傳值以及反參接收

BBB 頁(yè)面 push 到 CCC,并等待 CCC 回來(lái)時(shí)的反參劫谅。

class BBB extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      appBar: AppBar(
        title: Text('BBB'),
      ),
      body: Center(
        child: RaisedButton(
          child: Text('點(diǎn)擊前往CCC'),
          onPressed: (){
            var backValueFromDDD = Navigator.pushNamed(context, '/ccc',arguments: {'value': "我是BBB頁(yè)面?zhèn)鬟^(guò)來(lái)的值"});
            backValueFromDDD.then((value){
              print("CCC 傳回來(lái)反參了见坑,${value}");
            });
            // Navigator.pushNamedAndRemoveUntil(context, '/ccc', (route) => route.isCurrent);
          },
        ),
      ),
    );
  }
}

我們使用 then 屬性來(lái)接收下一個(gè)頁(yè)面 pop 回來(lái)帶的參數(shù)。

8.2 路由接收正向傳值以及反向傳參

我們?cè)?CCC 類中增加以下代碼捏检。

  Widget build(BuildContext context) {
    // TODO: implement build
    var value = ModalRoute.of(context).settings.arguments;
    print("BBB 頁(yè)面帶過(guò)來(lái)參數(shù)了荞驴,${value}");

    return Scaffold(
      appBar: AppBar(
        title: Text('CCC'),
      ),
      body: _listView(context),
    );
  }
        ListTile(
          title: Text("Navigator.of(context).pop 傳參"),
          onTap: (){
            Navigator.of(context).pop({"value":"我是CCC頁(yè)面帶回來(lái)的值"});
          },
        ),

8.3 打印效果

route argument.gif

8.4 其他寫法

在 BBB 中可以嘗試以下寫法,可以達(dá)到相同效果贯城。

class BBB extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      appBar: AppBar(
        title: Text('BBB'),
      ),
      body: Center(
        child: RaisedButton(
          child: Text('點(diǎn)擊前往CCC'),
          onPressed: () async {
            var backValueFromDDD = await Navigator.pushNamed(context, '/ccc',arguments: {'value': "我是BBB頁(yè)面?zhèn)鬟^(guò)來(lái)的值"});
            backValueFromDDD;
            print(backValueFromDDD);
            // Navigator.pushNamedAndRemoveUntil(context, '/ccc', (route) => route.isCurrent);
          },
        ),
      ),
    );
  }
}

9. 技術(shù)小結(jié)

  • 路由在App中是一個(gè)非常重要的功能熊楼,我已經(jīng)從事App開(kāi)發(fā)多年了,對(duì)頁(yè)面堆棧以及原理比較熟悉能犯,所以上手起來(lái)比較容易鲫骗。初學(xué)者需要更多耐心來(lái)理解和嘗試路由的各個(gè)方法。
  • 路由這一篇章花費(fèi)時(shí)間較多踩晶,踩坑也比較多执泰,為了盡可能的覆蓋到路由的全部用法,本文篇幅也比較長(zhǎng)渡蜻。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末术吝,一起剝皮案震驚了整個(gè)濱河市计济,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌排苍,老刑警劉巖沦寂,帶你破解...
    沈念sama閱讀 211,290評(píng)論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異纪岁,居然都是意外死亡凑队,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,107評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門幔翰,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)漩氨,“玉大人,你說(shuō)我怎么就攤上這事遗增〗芯” “怎么了?”我有些...
    開(kāi)封第一講書人閱讀 156,872評(píng)論 0 347
  • 文/不壞的土叔 我叫張陵做修,是天一觀的道長(zhǎng)霍狰。 經(jīng)常有香客問(wèn)我,道長(zhǎng)饰及,這世上最難降的妖魔是什么蔗坯? 我笑而不...
    開(kāi)封第一講書人閱讀 56,415評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮燎含,結(jié)果婚禮上宾濒,老公的妹妹穿的比我還像新娘。我一直安慰自己屏箍,他們只是感情好绘梦,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,453評(píng)論 6 385
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著赴魁,像睡著了一般卸奉。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上颖御,一...
    開(kāi)封第一講書人閱讀 49,784評(píng)論 1 290
  • 那天榄棵,我揣著相機(jī)與錄音,去河邊找鬼潘拱。 笑死秉继,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的泽铛。 我是一名探鬼主播,決...
    沈念sama閱讀 38,927評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼辑鲤,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼盔腔!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 37,691評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤弛随,失蹤者是張志新(化名)和其女友劉穎瓢喉,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體舀透,經(jīng)...
    沈念sama閱讀 44,137評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡栓票,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,472評(píng)論 2 326
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了愕够。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片走贪。...
    茶點(diǎn)故事閱讀 38,622評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖惑芭,靈堂內(nèi)的尸體忽然破棺而出坠狡,到底是詐尸還是另有隱情,我是刑警寧澤遂跟,帶...
    沈念sama閱讀 34,289評(píng)論 4 329
  • 正文 年R本政府宣布逃沿,位于F島的核電站,受9級(jí)特大地震影響幻锁,放射性物質(zhì)發(fā)生泄漏凯亮。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,887評(píng)論 3 312
  • 文/蒙蒙 一哄尔、第九天 我趴在偏房一處隱蔽的房頂上張望假消。 院中可真熱鬧,春花似錦究飞、人聲如沸置谦。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 30,741評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)媒峡。三九已至,卻和暖如春葵擎,著一層夾襖步出監(jiān)牢的瞬間谅阿,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 31,977評(píng)論 1 265
  • 我被黑心中介騙來(lái)泰國(guó)打工酬滤, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留签餐,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,316評(píng)論 2 360
  • 正文 我出身青樓盯串,卻偏偏與公主長(zhǎng)得像氯檐,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子体捏,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,490評(píng)論 2 348