Flutter中的路由管理,就是管理页面之间如何跳转。无论是Android还是iOS,导航管理都会维护一个路由栈,路由入栈(push)操作对应打开一个新页面(或者叫新路由),路由出栈(pop)操作对应页面关闭操作,而路由管理主要是指如何来管理路由栈。
而路由管理需要用到以下组件,我们分别来认识一下。
Navigator
Navigator提供了一系列方法来管理路由栈:
- Future push(BuildContext context, Route route),此方法是静态方法:
Navigator.push(BuildContext context, Route route)
对应的实例方法是:
Navigator.of(context).push(Route route)
- bool pop(BuildContext context, [ result ])
result为页面关闭时返回给上一个页面的数据。
MaterialPageRoute
MaterialPageRoute用来构建Route,构建函数如下:
MaterialPageRoute({
WidgetBuilder builder,
RouteSettings settings,
bool maintainState = true,
bool fullscreenDialog = false,
})
- builder:是一个WidgetBuilder类型的回调函数,作用是构建路由页面的实例,返回一个widget。
- settings:包含路由的配置信息,如路由名称、是否初始路由(首页)。
- maintainState:默认情况下,当入栈一个新路由时,原来的路由仍然会被保存在内存中,如果想在路由没用的时候释放其所占用的所有资源,可以设置为false。
- fullscreenDialog:在iOS中,如果fullscreenDialog为true,新页面将会从屏幕底部滑入。
以上的方式是非命名路由,下面我来讲一下命名路由。
命名路由
所谓命名路由,无非就是先给路由起一个名字,然后就可以通过路由名字直接打开新的路由了,这为路由管理带来了一种直观、简单的方式。
我们可以通过注册路由表的方式,然后通过路由名字打开新路由时,在路由表中,一个名字对应一个生成相应的路由的回调函数,应用会根据路由名字在路由表中查找到对应的回调函数(WidgetBuilder),然后调用该回调函数生成路由widget并返回。
MaterialApp(
title: 'Flutter Demo',
initialRoute:"/home", //名为"/home"的路由作为应用的首页
theme: ThemeData(
primarySwatch: Colors.blue,
),
//注册路由表
routes:{
"new_page":(context) => NewRoute(),
"/home":(context) => MyHomePage(title: 'Demo Home Page'), //注册首页路由
}
);
要通过路由名称来打开新路由,也很简单:
Navigator.pushNamed(context, "new_page");
或者:
Navigator.of(context).pushNamed("new_page", arguments: "hi");
我们看到上面的第二个push方法中传递一个参数'hi',那么在新路由中实际上可以通过RouteSetting对象获取这个参数:
class EchoRoute extends StatelessWidget {
@override
Widget build(BuildContext context) {
//路由参数
var args=ModalRoute.of(context).settings.arguments;
//...
}
}
onGenerateRoute
MaterialApp有一个onGenerateRoute属性,当调用Navigator.pushNamed(...)打开命名路由时,如果指定的路由名在路由表中已注册,则会调用路由表中的builder函数来生成路由组件;如果路由表中没有注册,就会调用onGenerateRoute来生成路由。一般我们可以在该回调中进行统一的权限控制,比如:
MaterialApp(
... //省略
onGenerateRoute:(RouteSettings settings){
return MaterialPageRoute(builder: (context){
String routeName = settings.name;
// 如果访问的路由页需要登录,但当前未登录,则直接返回登录页路由,
// 引导用户登录;其它情况则正常打开路由。
}
);
}
);
WillPopScope
Flutter中可以通过WillPopScope来实现导航返回按钮拦截。其默认构造函数如下:
const WillPopScope({
...
@required WillPopCallback onWillPop,
@required Widget child
})
其中,onWillPop是一个回调函数,当用户点击返回按钮时被调用。该回调需要返回一个Future对象,如果返回的Future最终值为false时,则不会返回;如果最终值为true时,当前路由出栈退出。我们需要提供这个回调来决定是否退出。
举个例子,为了防止用户误触返回键退出,我们设定当用户在1秒内点击两次返回按钮时,则退出;如果间隔超过1秒则不退出,并重新记时。代码如下:
class TestRoute extends StatefulWidget {
@override
TestRouteState createState() {
return new TestRouteState();
}
}
class TestRouteState extends State<TestRoute> {
DateTime _lastClickTime; //上次点击时间
@override
Widget build(BuildContext context) {
return new WillPopScope(
onWillPop: () async {
if (_lastClickTime == null ||
DateTime.now().difference(_lastClickTime) > Duration(seconds: 1)) {
//两次点击间隔超过1秒则重新计时
_lastClickTime = DateTime.now();
return false;
}
return true;
},
child: Container(
alignment: Alignment.center,
child: Text("test demo"),
)
);
}
}
网友评论