zoukankan      html  css  js  c++  java
  • flutter Route路由基本用法

    https://blog.csdn.net/senkai123/article/details/102948524

    Flutter 命名路由、路由组、路由退出、路由堆栈

    在flutter中需要进行页面跳转,也是需要用到路由Route,关键Navigator与Route,Navigator负责单元Route路由,压入和弹出,单元路由也就是我们需要跳转页面 ,比如HomePage()

    Navigator关键使用的4个属性

    •initialRoute: 初始路由的,也就是进入APP,默认页面

    •onGenerateRoute: 路由拦截器

    •onUnknownRoute: 找不到页面,也就是404

    •routes : 路由集合,也就在执行路由跳转的时候,会到路由集合里面的子路由进行匹配,如果匹配 到那么就调整到指定页面

    路由跳转 方式:

    1.通过路由名打开新路由页面

    通过路由名称来打开新路由,可以使用Navigator 的pushNamed方法:

    Future pushNamed(BuildContext context, String routeName,{Object arguments})

    1

    调用:

    onPressed: () {

    //不带参数

      Navigator.pushNamed(context, "new_page");

      //带参数,可以指定单个参数,或者多个, arguments: {}

      Navigator.of(context).pushNamed("new_page", arguments: "hi");

    },

    页面承接带过来的参数

      String tmp = ModalRoute.of(context).settings.arguments.toString();

    1

    2.匿名路由打开新路由页面

    Navigator.push( context, MaterialPageRoute(builder: (context) {

                  return HomePage();

               }));

    传参:

      final Map<String, WidgetBuilder> _routes = {

        '/sign': (context, {arguments}) => SignPage(arguments: arguments),

      };

    接参:

    class SignPage extends StatelessWidget {

      final Map arguments;

      SignPage({Key key, this.arguments}) : super(key: key) {

      }

      @override

      Widget build(BuildContext context) {

        String tmp2 = this.arguments.toString();

      }

    }

    路由集合(路由表)与onGenerateRoute的关系

    onGenerateRoute接受一个 Route 工厂函数

    final RouteFactory onGenerateRoute;

    1

    路由拦截源码,从拦截到路由之后,首先从路由表中拿到路由的 builder,如果能够拿到 builder,则判断是否存在 RouteSettings,如果存在则直接通关构造函数的 arguments 传递给页面 Page Widget。本质就是按照路由名字匹配路由表,然后跳转到正确页面中

    Route _routeGenerator(RouteSettings settings) {

        final String name = settings.name;

        final Function pageBuilder = this._routes[name];

        if (pageBuilder != null) {

          if (settings.arguments != null) {

            // 如果透传了参数

            return MaterialPageRoute(

                builder: (context) =>

                    pageBuilder(context, arguments: settings.arguments));

          } else {

            // 没有透传参数

            return MaterialPageRoute(builder: (context) => pageBuilder(context));

          }

        }

        return MaterialPageRoute(builder: (context) => HomeContent());

      }

    路由的使用方式

    第一个种,初始化执行路线,initialRoute -> onGenerateRoute -> onUnknownRoute, 路由跳转Navigator.pushNamed(context, “secondPage”); ,之后会到onGenerateRoute ,进行路由拦截匹配,如果能正确匹配到,那么跳转到指定页面

    例子:

    import 'package:flutter/material.dart';

    class NavigatorPage extends StatefulWidget {

     @override

     _NavigatorPageState createState() => _NavigatorPageState();

    }

    class _NavigatorPageState extends State<NavigatorPage> {

     @override

     Widget build(BuildContext context) {

      return Scaffold(

       appBar: AppBar(

        title: Text('Navigator'),

       ),

       body: Column(

        children: <Widget>[

         Text('Navigator的高度为infinity'),

         Text('如果直接父级非最上级也是infinity会产生异常'),

         Container(

          height: 333,

          color: Colors.amber.withAlpha(111),

          child: Navigator( // Navigator

           initialRoute: '/abc',

           onGenerateRoute: (val) {

            RoutePageBuilder builder;

            switch (val.name) {

             case '/abc':

              builder = (BuildContext nContext, Animation<double> animation, Animation<double> secondaryAnimation) => Column(

               // 并没有在 MaterialApp 中设定 /efg 路由

               // 因为Navigator的特性 使用nContext 可以跳转 /efg

               children: <Widget>[

                Text('呵呵呵'),

                RaisedButton(

                 child: Text('去 /efg'),

                 onPressed: () {

                  Navigator.pushNamed(nContext, '/efg');

                 },

                )

               ],

              );

             break;

             case '/efg':

              builder = (BuildContext nContext, Animation<double> animation, Animation<double> secondaryAnimation) => Row(

               children: <Widget>[

                RaisedButton(

                 child: Text('去 /hhh'),

                 onPressed: () {

                  Navigator.pushNamed(nContext, '/hhh');

                 },

                )

               ],

              );

             break;

             default:

              builder = (BuildContext nContext, Animation<double> animation, Animation<double> secondaryAnimation) => Center(

               child: RaisedButton(

                child: Text('去 /abc'),

                onPressed: () {

                 Navigator.pushNamed(nContext, '/abc');

                },

               )

              );

            }

            return PageRouteBuilder(

             pageBuilder: builder,

             // transitionDuration: const Duration(milliseconds: 0),

            );

           },

           onUnknownRoute: (val) {

            print(val);

           },

           observers: <NavigatorObserver>[]

          ),

         ),

         Text('Navigator执行寻找路由顺序'),

         Text('initialRoute'),

         Text('onGenerateRoute'),

         Text('onUnknownRoute'),

        ],

       ),

      );

     }

    }

    第二个种,初始化执行路线,routes ->onUnknownRoute,路由跳转Navigator.pushNamed(context, “secondPage”);,之后会到routes 路由集合之后,能匹配到正确的路由子路由,那么就跳转到子路由中

    例子:

    import 'package:flutter/material.dart';

    import 'package:flutter_routes/errorpage.dart';

    import 'package:flutter_routes/homepage.dart';

    import 'package:flutter_routes/navigator_with_result.dart';

    import 'package:flutter_routes/page1.dart';

    import 'package:flutter_routes/page2.dart';

    import 'package:flutter_routes/page3.dart';

    import 'package:flutter_routes/page4.dart';

    import 'package:flutter_routes/page5.dart';

    import 'package:flutter_routes/pageroutebuilderresult.dart';

    import 'package:flutter_routes/splash.dart';

    import 'package:flutter_routes/testpageroutebuilder.dart';

    import 'package:flutter_routes/todo.dart';

    import 'package:flutter_routes/welcome.dart';

    void main() => runApp(MyApp());

    class MyApp extends StatelessWidget {

      @override

      Widget build(BuildContext context) {

        return MaterialApp(

          title: 'Flutter路由',

          theme: ThemeData(

            primarySwatch: Colors.blue,

          ),

    //      路由集合

          routes: {

            '/page1': (context) => Page1(),

            '/page2': (context) => Page2(),

            '/page3': (context) => Page3(),

            '/page4': (context) => Page4(),

            '/page5': (context) => Page5(),

            '/todo': (context) => TodosScreen(),

            '/splash': (context) => Splash(),

            '/welcome': (context) => Welcome(),

            '/homepage': (context) => HomePage(),

            '/PageRouteBuilder': (context) => TestPageRouteBuilder(),

            '/PageRouteBuilderResult': (context) => PageRouteBuilderResult(),

          },

    //      找不到路由,显示的错误页面

          onUnknownRoute: (RouteSettings setting) {

            String name = setting.name;

            print("未匹配到路由:$name");

            return new MaterialPageRoute(builder: (context) {

              return new ErrorPage();

            });

          },

          home: Page1(),

        );

      }

    }

    Page1 页面

    import 'package:flutter/foundation.dart';

    import 'package:flutter/material.dart';

    class Page1 extends StatelessWidget {

      Page1({Key key}) : super(key: key);

      @override

      Widget build(BuildContext context) {

        return Scaffold(

          appBar: AppBar(

            title: Text('page1'),

          ),

          body: Center(

            child: RaisedButton(

              child: Text('跳转到Page2'),

              onPressed: () {

    //            路由跳转

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

              },

            ),

          ),

        );

      }

    }

    在实际开发过程中,建议用命名路由方式来跳转新的页面,便于维护,开发项目

    路由堆栈的使用方式

    1、在用这种方式路由跳转新页面的时候,是把页面放在堆栈里面,这个栈的特性就是,先进后出, Navigator.push 或者 pushNamed 实现的,每次都是把页面压入堆栈,在回退 的时候会回退到上一跳页面

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

    1

    2.如果需要清空堆栈,比如我需要直接返回首页,之前的所有路由全部干掉,堆栈清空

    Navigator.of(context).pushNamedAndRemoveUntil

    1

    页面退出堆栈

     Navigator.pop(context, "我是返回值"),

    1

    参考文章

    https://blog.csdn.net/weixin_30512027/article/details/85334391

    https://blog.csdn.net/weixin_34999505/article/details/86760606

    ————————————————

    版权声明:本文为CSDN博主「逐流间隔年」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。

    原文链接:https://blog.csdn.net/senkai123/java/article/details/102948524

  • 相关阅读:
    实现页面切换(动画效果实现,不用ViewPager)
    “仅仅生一个娃”--设计模式中的单例模式
    ZOJ
    【J2SE高速进阶】——多线程之synchronized
    [LeetCode] Search a 2D Matrix II
    leetCode 58.Length of Last Word (最后单词的长度) 解题思路和方法
    [CentOS]怎样解决gcc版本号冲突?
    从0开始学习 GITHUB 系列之「GITHUB 常见的几种操作」【转】
    从0开始学习 GITHUB 系列之「向GITHUB 提交代码」【转】
    从0开始学习 GITHUB 系列之「GIT 速成」【转】
  • 原文地址:https://www.cnblogs.com/sundaysme/p/12628706.html
Copyright © 2011-2022 走看看