Flutter之路由管理

1.MaterialPageRoute

MaterialPageRoute继承自PageRoute类,PageRoute类是一个抽象类,表示占有整个屏幕空间的一个模态路由页面,它还定义了路由构建及切换时过渡动画的相关接口及属性。MaterialPageRoute 是Material组件库提供的组件,它可以针对不同平台,实现与平台页面切换动画风格一致的路由切换动画:

关于MarterialPageRoute的构造器参数:

MaterialPageRoute({
    WidgetBuilder builder,
    RouteSettings settings,
    bool maintainState = true,
    bool fullscreenDialog = false,
  })
  • builder : 是一个WidgetBuilder的回调函数,返回值是Widget,返回的是一个新路由的实例.
  • settings :包含路由的配置信息,如路由名称、是否初始路由(首页)。
class RouteSettings {
  /// Creates data used to construct routes.
  const RouteSettings({
    this.name,
    this.isInitialRoute = false,
    this.arguments,
  });
  • maintainState : 默认情况下,当入栈一个新路由时,原来的路由仍然会被保存在内存中,如果想在路由没用的时候释放其所占用的所有资源,可以设置maintainState为false
  • fullscreenDialog : 表示新的路由页面是否是一个全屏的模态对话框,在iOS中,如果fullscreenDialog为true,新页面将会从屏幕底部滑入(而不是水平方向)相当于IOS中的present()方法跳转界面

如果想自定义路由切换动画,可以自己继承PageRoute来实现.

Navigator

Navigator:是一个管理路由的组件,通过一个栈来管理活动路由集合(相当于IOS中的导航控制器)

Future push(BuildContext context, Route route)

将给定的路由入栈(即打开新的页面),返回值是一个Future对象,用以接收新路由出栈(即关闭)时的返回数据。

bool pop(BuildContext context, [ result ])

将栈顶路由出栈,result为页面关闭时返回给上一个页面的数据。

实例方法

Navigator类中第一个参数为context的静态方法都对应一个Navigator的实例方法, 比如Navigator.push(BuildContext context, Route route) 等价于Navigator.of(context).push(Route route)

命名路由

要使用命名路由,我们首先要注册一个路由表

Map<String, WidgetBuilder> routes;

类似这种定义:

Map<String, WidgetBuilder> routes = {
  'Controller demo': (BuildContext context){ return ControllerDemoPage(title: 'Controller demo');},//没有省略的写法
  'Clip demo' : (BuildContext context) => ClipDemoPage(title: 'Clip demo'),//省略写法
  'Scroll demo' : (BuildContext context) => ScrollListenerDemoPage(title: 'Scroll demo'),
  'ScolllToIndex demo' : (context) => ScrollToIndexDemoPage(title: '列表滑动到制定位置'),
  'Refresh demo' : (context) => RefreshDemoPage(),
};

跳转时可以这样写:

Navigator.push(context, MaterialPageRoute(
                    builder: routes[routeNames[index]],
                  ));

也可以直接在MaterialApp的属性中直接声明:

MaterialApp(
  title: 'Flutter Demo',
  theme: ThemeData(
    primarySwatch: Colors.blue,
  ),
  //注册路由表
  routes:{
   "new_page":(context)=>NewRoute(),
    ... // 省略其它路由注册信息
  } ,
  home: MyHomePage(title: 'Flutter Demo Home Page'),
);

如果我们想把home: 属性后面的 路由也注册在表中,可以这样设置

MaterialApp(
  title: 'Flutter Demo',
  initialRoute:"/", //名为"/"的路由作为应用的home(首页)
  theme: ThemeData(
    primarySwatch: Colors.blue,
  ),
  //注册路由表
  routes:{
   "new_page":(context)=>NewRoute(),
   "/":(context)=> MyHomePage(title: 'Flutter Demo Home Page'), //注册首页路由
  } 
);

通过路由名打开新路由

Future pushNamed(BuildContext context, String routeName,{Object arguments})
除此之外API中还有许多其他的方法,请查看API详细了解

简单实现电商app的权限控制

假设我们要开发一个电商APP,当用户没有登录时可以看店铺、商品等信息,但交易记录、购物车、用户个人信息等页面需要登录后才能看。为了实现上述功能,我们需要在打开每一个路由页前判断用户登录状态!如果每次打开路由前我们都需要去判断一下将会非常麻烦,那有什么更好的办法吗?答案是有!

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

Route Function(RouteSettings settings

有了onGenerateRoute回调,要实现上面控制页面权限的功能就非常容易:我们放弃使用路由表,取而代之的是提供一个onGenerateRoute回调,然后在该回调中进行统一的权限控制,如:

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

注意,onGenerateRoute只会对命名路由生效,也就是Navigator.pushName()。


本文参考链接 :https://book.flutterchina.club/chapter2/flutter_router.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值