You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter Navigator 2.0实现页面返回结果及路由包选型咨询

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.02 06:31:11