记录自学flutter点点滴滴

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

2020-08-24  本文已影响0人  Tsm_2020

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

上一篇 下一篇

猜你喜欢

热点阅读