onPopPage 和 route.didPop
来源:7-6 实战--实现页面导航管理(四)

demonCry
2022-09-08
Navigator(
key: navigatorKey,
// 通过一个list来保存的 但其实还是一个栈的结构 只不过我们能通过list的特性来交换里面页面的顺序
pages: List.of(_pages),
//Called when [pop] is invoked but the current [Route] corresponds to a [Page] found in the [pages] list.
onPopPage: _onPopPage,
);
bool _onPopPage(Route route, dynamic result){
if(!route.didPop(result)) return false;
if(_canPop()){
_pages.removeLast();
return true;
} else {
return false;
}
}
- onPopPage 是在我们调用
Navigator.pop(context,true)
或 我们自定义的router.popRoute
时候调用的吗? - 这里调用 route.didPop 是干什么的 ?
- _onPopPage 里返回 true 和 false 有什么意义?区别?
- Navigator.pop(context,true) 第二个参数写true和false又有什么区别?
1回答
-
马超老师
2022-09-10
1、注意onPopPage是在创建Navigator的时候传入的,所以只有在调用Navigator.pop之后,此时系统会回调onPopPage函数。故自定义的router.popRoute是不会触发onPopPage回调的;
2、route里面didpop方法的作用是在底层路由栈中弹出指定页面,如果弹出成功则返回true,此时我们在pages列表中同步移除该页面;如果系统弹出失败则返回false(特殊情况才会),那么我们的pages也保持不变,直接return即可。
(扩展知识:通常情况下我们需要保持系统底层路由栈和我们的pages一致,如果不一致系统就会以当前pages为准,将多余的page当做新页面,再生成一个新的route对象,这样做的目的还是要保持底层路由栈中的内容上层 pages 数据一致,这里主要是需要注意要同步更新pages即可)
3、onPopPage的返回值表示是否允许当前页面弹出。返回true则顺利退出,返回false页面不会弹出。
这个是为了解决早期Navigator的使用问题。这样可以让页面是否关闭完全由开发者掌控,而不是单纯地交给系统的Navigator.pop()。
当你在某种场景下(比如页面栈只有最后一个页面)不希望Navigator弹出页面的时候,可以在onPopPage回调中返回false阻止返回。你可以尝试一下, 如果把onPopPage返回值改成false,然后调用Navigator.pop(),是没办法返回页面的。
4、Navigator.pop()的第二个参数是一个泛型类型,用于在弹出页面的时候给上一个页面返回值。项目中是点确认返回true,点取消返回false。当然也可以根据实际业务场景返回其他类型变量。
可能第二点当中的路由栈维护会有点不好理解,这里可以简单理解为,在系统移除页面后需要同步更新pages列表的状态。其他的还有解释不清楚的欢迎留言。
00
相似问题