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

Flutter使用popUntil传值至前页面时遇Cannot modify unmodifiable map错误

Flutter popUntil传递数据时触发"无法修改不可变映射"错误解决

错误信息

未处理的异常:不支持的操作:无法修改不可变映射
原错误日志:

[VERBOSE-2:ui_dart_state.cc(198)] Unhandled Exception: Unsupported operation: Cannot modify unmodifiable map

操作流程

1) 路由配置

Route<dynamic> generateRoute(RouteSettings settings) {
  switch (settings.name) {

    case LoginViewRoute:
      String navigatedScreen = settings.arguments as String;
      return MaterialPageRoute(
          settings:  RouteSettings(name: LoginViewRoute, arguments: Map()),
          builder: (context) => LoginPage(
                navigatedPage: navigatedScreen,
              ));

 }
}

2) 页面跳转(从Home页跳转到Login页)

Navigator.pushNamed(context, LoginViewRoute, arguments: HomeViewRoute).then((value) {
                final arguments = ModalRoute.of(context)?.settings.arguments as Map;
                bool result = arguments[IS_LOGIN_COMPLTED];
                if (result) {
                  _bloc.onLoggedIn();
                  print(User().email);
                }
              });

3) 返回数据处理(Login页中执行)

Navigator.of(context).popUntil((route) {
                        if (route.settings.name == widget.navigatedPage) {
                          (route.settings.arguments as Map)[IS_LOGIN_COMPLTED] = true;
                          return true;
                        } else {
                          return false;
                        }

错误触发点:

(route.settings.arguments as Map)[IS_LOGIN_COMPLTED] = true;

错误原因

Flutter的RouteSettings.arguments默认会被包装为不可变映射(UnmodifiableMapView),即使初始传入的是可变Map,Flutter内部也可能将其转为不可变实例,直接修改会触发上述异常。此外,RouteSettings设计初衷是传递路由初始化参数,并非页面间返回数据的载体。

解决方案

方案1:使用Navigator.pop返回数据(推荐)

这是Flutter页面间传递返回数据的标准方式,无需修改路由参数:

修改跳转页的回调逻辑(Home页)

Navigator.pushNamed(context, LoginViewRoute, arguments: HomeViewRoute).then((loginResult) {
  // 直接接收pop返回的数据
  if (loginResult == true) {
    _bloc.onLoggedIn();
    print(User().email);
  }
});

修改Login页的返回逻辑

Navigator.of(context).popUntil((route) {
  if (route.settings.name == widget.navigatedPage) {
    // 向目标页面返回数据
    Navigator.of(context).pop(true);
    return true;
  } else {
    return false;
  }
});

若只需返回上一级页面,无需跳过中间路由,可简化为:

Navigator.pop(context, true);

方案2:确保目标路由的arguments为可变Map(不推荐)

若坚持通过修改RouteSettings.arguments传递数据,需保证目标路由(如Home页)在创建时传入可变空Map:

// 修改HomeViewRoute的路由配置
case HomeViewRoute:
  return MaterialPageRoute(
    settings: RouteSettings(name: HomeViewRoute, arguments: {}), // 传入可变Map
    builder: (context) => HomePage(),
  );

这种方式不符合Flutter路由设计规范,易引发后续维护问题,谨慎使用。


内容的提问来源于stack exchange,提问作者kokoko

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 09:24:27