美文网首页记录自学flutter点点滴滴
Flutter 学习之旅(二十一) 路由管理

Flutter 学习之旅(二十一) 路由管理

作者: Tsm_2020 | 来源:发表于2020-08-24 15:05 被阅读0次

    Navigator

    Navigator是一个路由管理组件,他提供了打开和关闭页面的方法,同时打开关闭弹窗也是一样的原理
    在flutter中打开一个页面可以使用简单粗暴的方法,即

         Navigator.of(context).push(MaterialPageRoute(builder: (context){
              return TsmScaffoldPage();
            },settings: RouteSettings(arguments: 'value')));
    

    此种打开方式可以直接打开任何页面,但是由于在实际开发过程中这么写比较零散,不推荐这么写,

    打开命名路由

    在MaterialApp();

    MaterialApp(
          title: 'Flutter Demo',
          theme: ThemeData(
            primarySwatch: Colors.blue,
            visualDensity: VisualDensity.adaptivePlatformDensity,
          ),
          routes: {
            page_routes_container: (context) => TsmContainerPage(),
            page_routes_scaffold: (context) => TsmScaffoldPage(),
            page_routes_appbar: (context) => TsmAppBarPage(),
            page_routes_row_and_column: (context) => TsmRowAndColumnPage(),
            page_routes_text: (context) => TsmTextPage(),
            page_routes_text_field: (context) => TsmTextFieldPage(),
            page_routes_raised_button: (context) => TsmRaisedButtonPage(),
            page_routes_icon: (context) => TsmIconPage(),
            page_routes_iamge: (context) => TsmImagePage(),
            page_routes_single_child_scroll_view: (context) =>
                TsmSingleChildScrollViewPage(),
            page_routes_scroll_base: (context) => ScrollBasePage(),
            page_routes_grid_view: (context) => TsmGridViewPage(),
            page_routes_list_view: (context) => TsmListViewPage(),
          },
          home: TsmMainPage(),
        );
    

    首先需要在MaterialApp 的 routes 下面配置一个路径和widget的对应关系,
    在这里你会发现这样的跳转比上面那个跳转清晰多了,
    再来一个打开命名路由的方法

    //打开一个页面
    Navigator.of(context).pushNamed(page_routes_appbar,arguments: 'test');
    
    ///打开一个页面,并获取他的返回值
    Navigator.of(context).pushNamed(page_routes_appbar,arguments: 'test').then((value) => printString(value));
    
    
    //类似android setResult方法,设置返回值
    Navigator.pop(context, "返回值")
    

    MaterialPageRoute

    先来看一下构造方法

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

    MaterialPageRoute是Material 库中提供的组件,针对不同平台使用不同的打开动画,
    android 从底部向上打开 从顶部向下关闭
    ios 从右向左打开 从左向右关闭
    再来看一下他的参数,
    builder 返回需要打开的页面
    setting 其中包括name 与 arguments 一个是路由器名,还有携带参数
    maintainState 源码中是这样描述的, 默认情况下,当入栈一个新路由时,原来的路由仍然会被保存在内存中,如果想在路由没用的时候释放其所占用的所有资源,可以设置maintainState为false。感觉这样会释放他所持有的资源数据,

    上面两种方法你都看到有一个arguments的地方我随便写了一个参数,这个就是打开下一个页面携带的入参,在下一个页面获取参数的方法为,

    var arguments=ModalRoute.of(context).settings.arguments;
    

    其实对于我来说,这两个打开的方式其实都有点不完美,我先来说一下我的需求吧,

    1.最主要的需求,他需要看起来比较清晰,到底打开哪一个页面不能在页面中体现,要不然太乱,

    2.可以在打开页面之前做一些判断,比如登录 补全信息等

    3.思路清晰

    例子

      
        Map<String, Widget> _route = {
          page_routes_container: TsmContainerPage(),
          page_routes_scaffold: TsmScaffoldPage(),
          page_routes_appbar: TsmAppBarPage(),
          page_routes_row_and_column: TsmRowAndColumnPage(),
          page_routes_text: TsmTextPage(),
          page_routes_text_field: TsmTextFieldPage(),
          page_routes_raised_button: TsmRaisedButtonPage(),
          page_routes_icon: TsmIconPage(),
          page_routes_iamge: TsmImagePage(),
          page_routes_single_child_scroll_view: TsmSingleChildScrollViewPage(),
          page_routes_scroll_base: ScrollBasePage(),
          page_routes_grid_view: TsmGridViewPage(),
          page_routes_list_view: TsmListViewPage(),
        };
    
    MaterialApp(
          ...//省略属性
    
    
    ///   经测试onGenerateRoute这个东西必须    与  routes  中的配置互斥,如果在routes 中配置了,则该回调不起作用,
    ///   注意这里可以获取到route的name 也就是路由的路径,可以利用map 来操作,先把map加载进来,
    ///   如果该路由路径存在于map中则获取map中的widget,如果没在就打开主页
    ///   这么做的好处就是便于拦击,还有像命名路由那样,地址与widget 一一对应,非常清晰
          onGenerateRoute: (settings) {
            printString('onGenerateRoute');
            return MaterialPageRoute(builder: (context) {
              String routeName = settings.name;
              printString(routeName);
              if(_route.containsKey(routeName)){
                return _route[routeName];
              }
              return TsmScaffoldPage();
            });
          },
    

    我学习flutter的整个过程都记录在里面了
    https://www.jianshu.com/c/36554cb4c804

    最后附上demo 地址

    https://github.com/tsm19911014/tsm_flutter

    相关文章

      网友评论

        本文标题:Flutter 学习之旅(二十一) 路由管理

        本文链接:https://www.haomeiwen.com/subject/ttrnjktx.html