Flutter中GoRouter导航至Todo页面时屏幕冻结,Navigator却正常
我在Flutter应用中用GoRouter管理路由,导航到特定待办事项详情页时屏幕冻结,但日志能正常打印,说明路由逻辑已执行。换成原生Navigator.push则完全正常,无冻结现象。
路由定义
static GoRoute _categoryTodosRoute() { return GoRoute( path: ':categoryId/todos', builder: (context, state) { final cid = state.pathParameters['categoryId']!; return _categoryTodosRouteBuilder(cid); }, routes: [ GoRoute( path: 'todo/:todoId', builder: (context, state) { final tid = state.pathParameters['todoId']!; log('${tid}'); return TodoView(); }, ), ], ); }
其中:categoryId/todos路由可正常访问,问题仅出在嵌套的todo/:todoId路由。
导航代码(GoRouter版本,出现冻结)
case _TodoMenuAction.view: context.go('/categories/${categoryModel.id}/todos/todo/${todoModel.id}'); break;
正常工作的Navigator版本
case _TodoMenuAction.view: Navigator.push( context, MaterialPageRoute(builder: (context) => TodoView()), ); break;
可能的原因及解决方案
1. 排查TodoView的初始化逻辑
既然Navigator能正常加载TodoView,说明问题可能出在GoRouter环境下TodoView的初始化:
- 检查TodoView是否在
initState或build方法中执行了同步阻塞操作(比如大量计算、同步IO),GoRouter的路由构建在主线程同步流程中执行,这类操作会直接导致UI冻结。 - 若有耗时操作,将其移至
Future.delayed或compute中异步执行,避免阻塞UI线程。
2. 检查路由路径匹配是否存在歧义
确认完整路由路径/categories/${categoryModel.id}/todos/todo/${todoModel.id}是否和其他路由规则冲突。可以尝试简化嵌套路由,改为独立路由测试:
// 临时修改为独立路由 GoRoute( path: '/categories/:categoryId/todos/todo/:todoId', builder: (context, state) { final tid = state.pathParameters['todoId']!; log('${tid}'); return TodoView(); }, ),
如果这样能正常工作,说明嵌套路由的路径匹配存在异常,需要检查父路由的路径定义是否有遗漏或错误。
3. 验证GoRouter版本是否存在已知bug
确保使用的GoRouter版本是最新稳定版,旧版本可能存在嵌套路由导航时的UI线程阻塞问题,升级到最新版后再测试。
4. 检查BuildContext是否正确
确认导航时使用的context是否属于GoRouter的Navigator层级。如果context来自GoRouter无法感知的子树,可能导致导航后UI无法正确更新。可以尝试用GoRouter.of(context).go()替代context.go():
case _TodoMenuAction.view: GoRouter.of(context).go('/categories/${categoryModel.id}/todos/todo/${todoModel.id}'); break;
5. 检查GoRouter全局配置冲突
确保GoRouter根配置没有错误,比如是否正确使用了Navigator的key,或者有没有在根路由中设置不必要的redirect逻辑导致阻塞。
内容的提问来源于stack exchange,提问作者TONI IVANOV
相关产品推荐
相关产品推荐

