Flutter Navigation 2.0中popRoute与onPopPage的区别及不触发问题
问题解答
为什么onPopPage不会被触发
你的onPopPage未触发和自定义RootBackButtonDispatcher本身没有关系,是你自己的返回逻辑处理方式导致的:
默认的RootBackButtonDispatcher.didPopRoute逻辑会调用Navigator.maybePop(),而Navigator内部执行pop操作时才会触发onPopPage回调。但你重写了didPopRoute之后,直接把返回事件转发到了自定义的popRoute方法,你在popRoute里是手动修改pages列表后触发重建,全程没有调用Navigator的pop/maybePop等方法,自然不会触发onPopPage。
popRoute和onPopPage的核心区别
popRoute是RouterDelegate的标准API,属于Navigator 2.0路由体系的顶层返回事件入口:系统返回事件首先会分发到Router,再调用你重写的popRoute方法,返回true代表当前路由栈消耗了本次返回事件,返回false代表路由栈无法再弹出,会交给系统处理(比如直接退出应用)。onPopPage是Navigator组件自带的回调,不管是旧版Navigator 1.0还是新版Navigator 2.0都可使用:只有当Navigator内部发起pop操作(比如调用Navigator.pop()、点击默认AppBar的返回按钮、默认maybePop逻辑执行)时才会触发,作用是校验本次pop操作是否合法,返回false可以拦截pop操作。
修复方案
如果你需要onPopPage触发,调整popRoute的逻辑即可:
@override Future<bool> popRoute() { final navigator = navigatorKey.currentState; if (navigator?.canPop() == true) { // 调用Navigator的pop方法,会自动触发onPopPage navigator?.pop(); return SynchronousFuture(true); } return SynchronousFuture(false); }
之后把pages修改的逻辑移到_onPopPage里就行:
bool _onPopPage(Route<dynamic> route, dynamic result) { if (!route.didPop(result)) return false; _removePage(viewModel.pages.last); viewModel.rebuild; return true; }
如果你已经习惯手动控制pages列表处理返回逻辑,不需要依赖onPopPage,保持现有代码也可以正常运行,属于Navigator 2.0的合法使用方式。
内容的提问来源于stack exchange,提问作者Andrey Solera
相关产品推荐
相关产品推荐

