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

调用ModalRoute.of(context)后ChangeNotifier类停止工作求助

问题解决:调用路由参数后ListController停止工作

问题根源

你在build方法内直接实例化ListController,而ModalRoute.of(context)?.settings.arguments会触发组件重建(比如路由参数变化时),每次重建都会创建全新的ListController实例,之前绑定的监听会直接失效,表现为控制器停止工作。

解决方案

需要让ListController实例在组件生命周期内保持稳定,以下是两种常用实现方式:

方式1:在StatefulWidget的initState中初始化控制器

将控制器实例放在State类中,仅在组件初始化时创建一次:

class YourPage extends StatefulWidget {
  const YourPage({super.key});

  @override
  State<YourPage> createState() => _YourPageState();
}

class _YourPageState extends State<YourPage> {
  late ListController detailController;

  @override
  void initState() {
    super.initState();
    // 仅初始化一次控制器
    detailController = ListController();
  }

  @override
  void dispose() {
    // 销毁控制器,避免内存泄漏
    detailController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    final arguments = ModalRoute.of(context)?.settings.arguments as List<Object?>;
    
    return Scaffold(
      body: Padding(
        padding: const EdgeInsets.all(8.0),
        child: DetailComponent(columns: columns, controller: detailController),
      ),
    );
  }
}

方式2:使用状态管理工具(跨组件共享场景)

如果需要在多个组件间共享控制器状态,可通过ChangeNotifierProvider提供全局唯一实例:

// 在页面父级或MaterialApp中注入控制器
ChangeNotifierProvider(
  create: (context) => ListController(),
  child: YourPage(),
)

// 在YourPage中获取控制器实例
final detailController = Provider.of<ListController>(context);

关键注意事项

  • 禁止在build方法内创建ChangeNotifier实例,build会因路由参数变化、父组件重建等频繁触发,每次都会生成新实例,导致状态丢失、监听失效。
  • 组件销毁时必须调用dispose()方法释放控制器资源,防止内存泄漏。

内容的提问来源于stack exchange,提问作者Iury Soares Azevedo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 17:37:11