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

为CupertinoPicker设置FixedExtentScrollController后页面切换报错

解决PageView切换后CupertinoPicker使用FixedExtentScrollController的断言错误

问题根源

当PageView切换到页面2时,未启用状态保持的页面1会被标记为不可见,其内部CupertinoPicker对应的RenderObject会被释放。但FixedExtentScrollController仍持有对该已释放RenderObject的监听,返回页面1操作Picker时,控制器发送滚动通知给已销毁的对象,触发!_debugDisposed断言错误。

解决方案

方法一:启用页面状态保持(推荐)

使用AutomaticKeepAliveClientMixin让页面1在切换时保持状态,避免RenderObject被释放,同时在State中正确管理控制器的生命周期。

class Page1 extends StatefulWidget {
  @override
  _Page1State createState() => _Page1State();
}

class _Page1State extends State<Page1> with AutomaticKeepAliveClientMixin {
  final FixedExtentScrollController _scrollController = FixedExtentScrollController();

  // 启用状态保持
  @override
  bool get wantKeepAlive => true;

  @override
  void dispose() {
    // 页面销毁时释放控制器
    _scrollController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    // 必须调用super.build,否则状态保持不生效
    super.build(context);
    return CupertinoPicker(
      scrollController: _scrollController,
      itemExtent: 50,
      onSelectedItemChanged: (index) {
        // 处理选中事件
      },
      children: List.generate(20, (index) => Center(child: Text('选项 $index'))),
    );
  }
}

方法二:重建控制器(适合不需要保留选中状态的场景)

如果不需要保留页面1的选中状态,可以在页面每次初始化时创建新的控制器,销毁时释放旧控制器,避免关联已释放的RenderObject。

class Page1 extends StatefulWidget {
  @override
  _Page1State createState() => _Page1State();
}

class _Page1State extends State<Page1> {
  late FixedExtentScrollController _scrollController;

  @override
  void initState() {
    super.initState();
    _scrollController = FixedExtentScrollController();
  }

  @override
  void dispose() {
    _scrollController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return CupertinoPicker(
      scrollController: _scrollController,
      itemExtent: 50,
      onSelectedItemChanged: (index) {},
      children: List.generate(20, (index) => Center(child: Text('选项 $index'))),
    );
  }
}

注意事项

  • 控制器必须在页面的State中创建,禁止使用全局控制器,否则会导致跨页面的状态冲突。
  • 使用状态保持时,确保wantKeepAlive返回true且build方法中调用super.build(context)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 13:45:47