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

ScrollablePositionedList滚动时表单反复重建丢失值,如何解决?

解决ScrollablePositionedList滚动时表单重建丢失输入值的问题

你的问题核心有两个:一是MyForm是无状态组件(StatelessWidget),输入值存在TextFormField的内部状态中,列表滚动回收item时,这些状态会被销毁;二是提前生成所有MyForm实例的方式,不符合列表builder的使用逻辑,反而容易导致状态管理混乱。

下面是具体的修复方案:

步骤1:将MyForm改为带状态保持的StatefulWidget

把无状态的MyForm改成Stateful,并混入AutomaticKeepAliveClientMixin,让组件在滚动出视口时保留状态:

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

  @override
  State<MyForm> createState() => _MyFormState();
}

class _MyFormState extends State<MyForm> with AutomaticKeepAliveClientMixin {
  final formKey = GlobalKey<FormState>();
  // 用变量保存输入值,替代TextFormField的内部状态(更稳妥)
  String _inputValue = '';

  @override
  bool get wantKeepAlive => true; // 关键:保持状态不销毁

  @override
  Widget build(BuildContext context) {
    super.build(context); // 必须调用,否则AutomaticKeepAlive不生效
    return Form(
      key: formKey,
      child: Column(
        children: [
          TextFormField(
            initialValue: _inputValue,
            onChanged: (value) {
              setState(() {
                _inputValue = value;
              });
            },
          ),
        ],
      ),
    );
  }
}

步骤2:修改列表构建逻辑,动态创建表单

不要提前生成所有MyForm实例,而是在ScrollablePositionedList.builder的itemBuilder里动态创建,同时给每个表单设置唯一的Key:

class MyContent extends StatelessWidget {
  final int itemCount;

  const MyContent(this.itemCount, {super.key});

  @override
  Widget build(BuildContext context) {
    return ScrollablePositionedList.builder(
      addAutomaticKeepAlives: true, // 配合AutomaticKeepAlive使用
      itemCount: itemCount,
      itemBuilder: (context, index) => MyForm(
        key: ValueKey(index), // 每个表单的唯一Key
      ),
    );
  }
}

步骤3:更新MyApp的调用方式

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'BLACK',
      home: Scaffold(
        body: const MyContent(100), // 直接传数量即可
      ),
    );
  }
}

额外说明

  • 用变量保存输入值(_inputValue)是更稳妥的方式,即使组件偶尔重建,也能通过initialValue恢复内容;
  • AutomaticKeepAliveClientMixin是Flutter官方提供的保持列表项状态的方案,专门解决滚动时组件销毁丢失状态的问题;
  • 确保每个列表项的Key唯一,Flutter才能正确识别组件,不会混淆不同的表单实例。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 00:25:24