Flutter从3.13.6升级到3.22后RouteAware导致页面重载求助
解决方法
1. 修正订阅时机,确保路由引用稳定
把订阅逻辑从initState的postFrameCallback移到didChangeDependencies中,同时在订阅新路由前取消旧订阅,避免路由引用异常导致的重建:
final RouteObserver<ModalRoute> routeObserver = RouteObserver<ModalRoute>(); class MyScreenState extends State<MyScreen> with RouteAware { ModalRoute? _currentRoute; @override void didChangeDependencies() { super.didChangeDependencies(); final newRoute = ModalRoute.of(context); if (newRoute != _currentRoute) { // 取消旧路由的订阅 if (_currentRoute != null) { routeObserver.unsubscribe(this); } // 订阅新路由 if (newRoute != null) { routeObserver.subscribe(this, newRoute); _currentRoute = newRoute; } } } @override void dispose() { if (_currentRoute != null) { routeObserver.unsubscribe(this); } super.dispose(); } }
2. 过滤Dialog路由的回调触发
如果页面不需要响应Dialog的路由事件,可以在RouteAware的回调中判断路由类型,跳过Dialog相关的处理,避免触发不必要的setState:
@override void didPushNext() { // 跳过Dialog路由的回调 if (nextRoute is DialogRoute) { return; } // 你的业务逻辑代码 } @override void didPopNext() { // 跳过Dialog关闭后的回调 final previousRoute = ModalRoute.of(context)?.previousRoute; if (previousRoute is DialogRoute) { return; } // 你的业务逻辑代码 }
原因说明
调用showDialog时,Flutter会将Dialog作为DialogRoute压入路由栈,此时RouteObserver会通知当前页面的RouteAware对象触发didPushNext回调。如果订阅逻辑存在路由引用不稳定、重复订阅,或者回调中触发了setState,就会导致页面重建。通过修正订阅时机和过滤Dialog路由,就能避免不必要的页面重载。
内容的提问来源于stack exchange,提问作者Vishnu
相关产品推荐
相关产品推荐

