Flutter中如何使用路由处理deeplink深度链接的页面跳转
问题根因
你代码里标注的问题是对的:当前调用Navigator.pushNamed的context是MyApp组件的context,处在MaterialApp的层级之上,而Navigator是MaterialApp内部才创建的,所以这个context根本找不到对应的Navigator实例,跳转自然失效。
解决方案
方案1:使用全局NavigatorKey(推荐,改动最小)
你可以通过全局key直接持有MaterialApp的Navigator实例,不需要依赖context就能触发跳转,修改步骤如下:
- 在
_MyAppState中定义Navigator的全局key
class _MyAppState extends State<MyApp> with SingleTickerProviderStateMixin { // 新增这一行 final _navigatorKey = GlobalKey<NavigatorState>(); // 剩下的原有变量不变 Uri _latestUri; Object _err; StreamSubscription _sub; // ... }
- 给
MaterialApp绑定navigatorKey参数
@override Widget build(BuildContext context) { return MaterialApp( // 新增这一行绑定key navigatorKey: _navigatorKey, initialRoute: 'splash-screen', // 剩下的onGenerateRoute等原有配置不变 // ... ); }
- 替换跳转逻辑,用全局key调用Navigator
// 原来的Navigator.pushNamed(context, 'login'); // 替换为下面的代码,如果需要传deeplink参数可以通过arguments携带 _navigatorKey.currentState?.pushNamed('login', arguments: _latestUri?.queryParameters);
方案2:下移deeplink监听逻辑
你也可以把_handleIncomingLinks的逻辑放到MaterialApp的子组件中实现,比如放在启动页SplashScreen的initState里,这时候拿到的context已经包含Navigator实例,可以直接调用跳转方法,适合需要结合启动逻辑做校验的场景。
额外注意事项
- 你当前的代码只处理了应用在后台被deeplink唤起的场景,冷启动场景下的初始deeplink需要单独调用
getInitialUri()方法获取,不要遗漏该场景的处理 - 跳转前可以先判断当前路由栈状态,避免重复push相同页面造成栈冗余
- 拿到uri后建议做合法性校验,避免非法deeplink触发异常跳转
内容的提问来源于stack exchange,提问作者Rutger Huijsmans
相关产品推荐
相关产品推荐

