Flutter Navigator 2.0实现页面返回结果及路由包选型咨询
原生Navigator 2.0实现Activity for Result能力
实现跳转后携带结果返回的核心是维护待完成请求映射表,不需要改动现有RouterDelegate的核心栈管理逻辑,仅需在push、pop节点做结果透传即可:
- 在自定义RouterDelegate子类中新增一个Map类型成员,key为跳转请求的唯一标识,value为对应请求的Completer对象,用于持有返回结果的Future。
- 改造现有
push方法:执行页面入栈前生成唯一requestId,将id绑定到入栈的Page对象上,同时新建对应泛型的Completer存入映射表,push方法直接返回该Completer的Future,调用方即可通过await等待返回结果。 - 改造现有
pop方法:执行原有出栈逻辑后,取出出栈Page绑定的requestId,从映射表中找到对应Completer,将pop传入的result参数通过complete方法传回给等待的调用方,最后移除映射表中的对应记录避免内存泄漏。
注意:安卓物理返回、iOS侧滑返回等系统触发的pop操作,需要在RouterDelegate的
popRoute回调中给对应Completer补传null结果,避免Future永久挂起引发内存泄漏。
核心实现代码参考:
// RouterDelegate内核心成员定义 final Map<String, Completer<dynamic>> _pendingResultMap = {}; int _autoIncrementId = 0; // 改造后的push方法 Future<T?> push<T>(Page targetPage) { final requestId = 'nav_${_autoIncrementId++}'; // 可自定义Page子类,增加requestId字段做绑定 final wrappedPage = CustomPage( child: targetPage.child, requestId: requestId, key: targetPage.key, name: targetPage.name, ); _pages.add(wrappedPage); notifyListeners(); final completer = Completer<T?>(); _pendingResultMap[requestId] = completer; return completer.future; } // 改造后的pop方法 void pop<T>([T? result]) { if (_pages.isEmpty) return; final poppedPage = _pages.removeLast() as CustomPage; notifyListeners(); final completer = _pendingResultMap.remove(poppedPage.requestId); if (completer != null && !completer.isCompleted) { completer.complete(result); } }
go_router与auto_route选型参考
两个包均处于稳定维护状态,无停更风险,可根据项目场景选择:
- 优先选go_router的场景:
- 项目为中小规模,路由逻辑简单,无复杂嵌套路由、定制化拦截需求
- 希望最小化模板代码量,快速接入全平台路由能力(含Web路由、深链支持)
- 倾向于和Flutter官方路由设计保持对齐:go_router由Flutter官方团队维护,API迭代和底层框架兼容性最优,遇到框架级兼容问题的概率最低
- 原生支持结果回传能力,无需额外封装,直接调用
await context.push('/path')即可拿到页面返回的结果,使用体验和原生Navigator 1.0基本一致。
- 优先选auto_route的场景:
- 项目为中大型规模,路由层级深、嵌套路由多,存在大量权限拦截、参数转译、路由守卫类需求
- 团队偏好类型安全的路由调用方式:auto_route通过代码生成生成强类型路由调用方法,传参可在编译期做类型检查,避免硬编码路由路径带来的错误
- 需要更高的路由定制自由度:比如自定义全局/单页转场动画、独立嵌套导航栈状态维护、Tab路由绑定等复杂场景,auto_route的可配置性显著高于go_router
- 同样原生支持结果回传,代码生成的push方法直接返回对应泛型的Future,无需额外封装。
两个包不存在绝对的优劣,核心是官方适配度和灵活度的权衡,按项目规模和团队编码习惯选择即可。
内容的提问来源于stack exchange,提问作者Ahmad Zafar
相关产品推荐
相关产品推荐

