Flutter中的路由函数

概述

Flutter中,路由(Router)即页面的封装,一个路由内部包含了一个页面。创建路由:

MaterialPageRoute route = MaterialPageRoute(
  builder: (BuildContext context) => MyPage(),
);

类似于在Android原生中以任务栈来管理Activity,在Flutter中以路由栈来管理路由。跳转到一个新页面,就是将其对应的路由加入到栈顶;退出一个页面,就是将其对应的路由出栈。

路由函数简介

push、pushNamed

将一个路由加入到栈顶,即跳转到一个新页面。

Navigator.push(context, MaterialPageRoute(builder: (BuildContext context) => Page2()));

Navigator.pushNamed(context, routerName);

pushReplacement、pushReplacementNamed

将一个路由加入到栈顶,并将当前路由出栈(pop)。(也就是以一个新页面替换当前页面。在新页面的入场动画结束时,才会调用当前页面的dispose方法。)

pushAndRemoveUntil、pushNamedAndRemoveUntil

将一个路由加入到栈顶,并将其下方的路由逐一移除(remove),直到predicate函数返回了true。

//调用方式
Navigator.pushAndRemoveUntil(context, newRoute, predicate);
Navigator.pushNamedAndRemoveUntil(context, newRouteName, predicate);

//下面代码将名为Page6的路由加入到栈顶,并将其下方的路由逐一出栈,直到遇到名为MyHomePage的路由:
Navigator.pushNamedAndRemoveUntil(context, "Page6", ModalRoute.withName('MyHomePage'));

//下面代码将名为Page6的路由加入到栈顶,并将其下方的路由全部出栈,即,使Page6成为路由栈中唯一的路由:
Navigator.pushNamedAndRemoveUntil(context, "Page6", (route){return false;});

需要注意的是,被移除(remove)的路由将永远不会变成completed状态,也就是说将它入栈的push、pushNamed的返回值future将永远不会被complete。

pop

将栈顶的路由出栈。

被出栈的路由会变成completed状态。也就是说将其入栈的push、pushNamed的返回值future也会变成completed状态。

风险:如果路由栈中只有唯一的路由,那么将此路由出栈后,app并不会像Android原生那样退出,而是会展示一个黑屏界面。(因此在Flutter中,为了避免黑屏,在调用pop方法之前,需要确定路由栈中是否只有唯一的路由。)

既然将唯一的路由出栈并不能关闭app,那么如果想要关闭app的话该怎么做呢?

方法1:
SystemChannels.platform.invokeMethod('SystemNavigator.pop');

此方法在IOS上会被忽略,因为IOS不允许应用退出自己。
  
方法2:
import 'dart:io';
...
exit(0);

此方法会立即结束Dart虚拟机进程。副作用正如文档所说:This does not wait for any asynchronous operations to terminate. Using exit is therefore very likely to lose data.

canPop、maybePop

上面提到,为避免黑屏,在调用pop方法之前,需要确定路由栈中是否只有唯一的路由。那么该如何确定呢?答案是通过canPop函数。当路由栈中只有唯一的一个路由时,canPop会返回false,其他情况都会返回true。因此可以这样使用:

if(Navigator.canPop(context)){
  Navigator.pop(context);
}

maybePop函数的情况比较复杂,它的行为在大部分情况下与if(Navigator.canPop(context)){Navigator.pop(context);}相同,但却远不止于此。使用时需要谨慎。

popUntil

重复调用pop方法使路由栈中的路由逐一出栈,直到predicate函数返回了true。

Navigator.popUntil(context, ModalRoute.withName("Page2"));

popAndPushNamed

将当前路由出栈,并将一个新路由加入到栈顶。

replace、replaceRouteBelow

//以一个新路由替换一个路由栈中已有的路由。
Navigator.replace(context, oldRoute, newRoute);

//以一个新路由替换一个路由栈中已有的路由。被替换的路由是位于anchorRoute下的那个路由。
Navigator.replaceRouteBelow(context, anchorRoute, newRoute);

//被替换的路由永远不会变成completed状态,也就是说将其入栈的push、pushNamed的返回值future也不会变成completed状态。
//被替换的路由不能是可见的,因为替换过程没有任何动画过渡,看起来会比较古怪。

removeRoute、removeRouteBelow

将指定的路由从任务栈中移除。

Navigator.removeRoute(context, route);
Navigator.replaceRouteBelow(context, anchorRoute);

//被remove的路由永远不会变成completed状态,也就是说将其入栈的push、pushNamed的返回值future也不会变成completed状态。
发布了46 篇原创文章 · 获赞 38 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/al4fun/article/details/101121244