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

Flutter中如何从动态列表正确移除StatefulWidget?

ListView移除StatefulWidget列表项异常的解决方法

当ListView的列表项为StatefulWidget时,移除中间项会出现异常:列表数据中已移除目标项,但屏幕上消失的却是最后一项。此前常见方案仅适用于StatelessWidget,以下是基于GlobalKey的解决方法:

1. 调整StatefulWidget列表项的构造

让列表项ItemWidget在构造时接收Key,确保Flutter能够正确识别每个组件的唯一身份:

class ItemWidget extends StatefulWidget {
  ItemWidget({required Key key}) : super(key: key); // 必须传入Key

  @override
  ItemWidgetState createState() {
    return ItemWidgetState();
  }
}

2. 实现列表组件的增删逻辑

核心操作是在移除列表项前,通过GlobalKey获取对应组件的状态并调用deactivate()方法,强制Flutter更新组件树的关联关系,避免渲染错乱:

class YourListViewWidget extends StatefulWidget {
  @override
  _YourListViewWidgetState createState() => _YourListViewWidgetState();
}

class _YourListViewWidgetState extends State<YourListViewWidget> {
  final List<ItemWidget> itemWidgets = List.empty(growable: true);
  final List<GlobalKey<ScaffoldState>> itemWidgetsKeys = List.empty(growable: true);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: ListView.builder(
        // controller: _scrollController, // 如需使用滚动控制器请提前定义
        itemCount: itemWidgets.length,
        itemBuilder: (context, count) {
          return itemWidgets[count];
        },
      ),
    );
  }

  void addItem() {
    setState(() {
      GlobalKey<ScaffoldState> key = GlobalKey();
      itemWidgetsKeys.add(key);
      itemWidgets.add(ItemWidget(key: key));
    });
  }

  void removeItem(int indexToRemove) {
    setState(() {
      GlobalKey<ScaffoldState> key = itemWidgetsKeys[indexToRemove];
      key.currentState?.deactivate(); // 关键步骤:先停用对应组件状态
      itemWidgets.removeAt(indexToRemove);
      itemWidgetsKeys.removeAt(indexToRemove);
    });
  }
}

注:此前尝试过StackOverflow上的相关方案,但仅支持StatelessWidget。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 16:10:20