最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • Flutter | 路由管理

    正文概述 掘金(345丶)   2021-01-08   491

    Flutter | 路由管理

    什么是路由?

    示例

    1,创建一个新的路由,命名 NewRoute

    /// StatelessWidget 无状态组件
    class NewRoute extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text("FlutterStudy"),
          ),
          body: Center(
            child: Text(
              "This is new route",
              style: Theme.of(context).textTheme.headline3,
            ),
          ),
        );
      }
    }
    

    2,创建一个文本按钮,点击进行跳转

    FlatButton(
        child: Text("点击跳转"),
        textColor: Colors.red,
        onPressed: () {
            //导航到新的路由
            Navigator.push(context, MaterialPageRoute(builder: (context) {
                return NewRoute();
            }));
        },
    )
    

    效果:Flutter | 路由管理

    MaterialPageRoute

    MaterialPageRoute 是 Material 组件库提供的组件,他可以针对不同的平台,实现与平台页面切换动画风格一致切换动画

    MaterialPageRoute 继承自 PageRoute 类,PageRoute 是一个抽象类,表示整个屏幕空间的一个模态路由页面,其中定义了路由构建及切换时过度动画的相关接口和属性;如果想自定义路由切换动画,可自己继承 PageRoute 来实现

    • 构造方法

      MaterialPageRoute({
        required this.builder,
        RouteSettings? settings,
        this.maintainState = true,
        bool fullscreenDialog = false,
      }) 
      
      • builder

        是 WidgetBuilder 类型的回调函数,它的作用是构建路由的具体内容,返回值是一个 widget;

        通常要实现此回调,返回新路由的实例

      • setting

        包含路由的配置信息,例:路由名称,是否初始路由等

      • maintainState

        默认情况下,当入栈一个新的路由时,原来的路由仍然会保存在内存中,如果想在路由没用的时候释放其所占用的资源,可以设置为 false

      • fullscreenDialog

        表示新的路由是否是一个全屏的模态对话框,在 ios 中若此参数为 true,新页面会从底部滑入,而不是水平方向

    Navigator

    Navigator 是一个路由管理组件,它提供了打开和退出路由方法

    Navigator 通过栈来管理活动路由集合,通常屏幕显示的页面就是栈顶路由

    打开一个页面

     static Future<T?> push<T extends Object?>(BuildContext context, Route<T> route) {
        return Navigator.of(context)!.push(route);
      }
    

    将给定的路由入栈(打开页面),返回 future 对象,用于接收该路由出栈是返回的数据。

    关闭一个页面

    static void pop<T extends Object?>(BuildContext context, [ T? result ]) {
      Navigator.of(context)!.pop<T>(result);
    }
    

    将栈顶路由出栈,reslut 为要返回给上一个页面的数据

    路由传值

    class TipRoute extends StatelessWidget {
      TipRoute({Key key, this.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),
                    RaisedButton(
                      onPressed: () => Navigator.pop(context, "我是返回值"),
                      child: Text("返回"),
                    )
                  ],
                ),
              )),
        );
      }
    }
    

    代码很简单,在界面中添加了一个 appbar,在中间显示一个文本,和一个 RaisedButton,并且点击进行 pop 并传入要返回的值

    class RouterTestRoute extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return Center(
          child: RaisedButton(
            onPressed: () async {
              await Navigator.push(context, MaterialPageRoute(builder: (context) {
                return TipRoute(text: "我是参数");
              })).then((value) => print("路由返回值 $value"));
            },
            child: Text("打开提示页面"),
          ),
        );
      }
    }
    

    在 onPressed 方法中,异步执行这个函数,最终将返回值打印出来

    如果不了解 async 可查看这篇文章,Dart,随用随查

    运行上面的代码,点击 "打开提示页面",效果如下所示

    Flutter | 路由管理

    打印的结果

    I/flutter (23778): 路由返回值 我是返回值
    

    需要注意的是

    ​ 1,参数是通过构造方法传入的

    ​ 2,如果点击左上角,或者返回按钮进行返回,则页面返回的值为 null

    命名路由

    有名字的路由,给路由起一个名字,就可以通过名字直接打开路由了

    路由表

    路由表就是一个 map,key 为路由名字,value 是一个 builder 的回调函数,用于生成相应的路由 widget。如下:

    final Map<String, WidgetBuilder>? routes;
    

    注册路由

    在 MaterialApp 里面,添加 routes 属性即可,如下:

    Widget build(BuildContext context) {
      return MaterialApp(
        //app name
        title: 'FlutterStudy',
        theme: ThemeData(
          primarySwatch: Colors.red,
        ),
        routes: {
          "new_page": (context) => NewRoute(),
          "/": (context) => MyHomePage(title: "Flutter Study")
        },
        //应用首页路由
        home: MyHomePage(title: 'Flutter Study'),
      );
    }
    

    打开路由页面

    TextButton(
    	child: Text("自定义 Button"),
    	onPressed: () {
    	Navigator.pushNamed(context, "router_test");
    })
    

    在点击的事件中,跳转到对于的路由页面

    带参数的命名路由传递

    routes: {
      "new_page": (context) => NewRoute(),
    },
    

    在路由表里面注册

    class NewRoute extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        var args = ModalRoute.of(context).settings.arguments;
    	//.......
    }
    

    接受参数

    Navigator.pushNamed(context, "new_page",arguments: "Hello World");
    

    在跳转的时候发送数据即可

    路由生成钩子

    在打开某些页面的时候可能需要做一些权限检测,如用户是否登录,是否需要密码等,如果每次打开路由的时候都要去判断一下会非常麻烦,这种情况可以通过 MaterialApp 实现

    MaterialApp 有一个 onGenerateRoute 属性,他在打开路由时可能会被调用,之所以说可能,是应为当调用 Navigator.pushNamed() 打开路由时,如果指定的路由在路由表中已经注册,则会调用路由表中的 builder 函数来生成路由组件;如果路由表中没有注册,才会调用 onGenerateRoute 来生成路由。

    MaterialApp(
      ... //省略无关代码
      onGenerateRoute:(RouteSettings settings){
          return MaterialPageRoute(builder: (context){
               String routeName = settings.name;
           // 如果访问的路由页需要登录,但当前未登录,则直接返回登录页路由,
           // 引导用户登录;其它情况则正常打开路由。
         }
       );
      }
    );
    

    参考资料:


    起源地下载网 » Flutter | 路由管理

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元