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

Flutter中如何持久化保存动态多表单的TextFormField数据

解决Flutter动态多表单页面切换后数据丢失的问题

方案1:页面保活(会话内临时留存)

如果仅需在返回主菜单再进入时保留页面数据、避免页面重建,可通过AutomaticKeepAliveClientMixin实现页面保活,阻止页面被销毁。

实现步骤:

  • 在主菜单项页面的State类中混入AutomaticKeepAliveClientMixin
  • 重写wantKeepAlive方法返回true
  • 在build方法中必须调用super.build(context)

示例代码:

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

  @override
  State<DynamicFormPage> createState() => _DynamicFormPageState();
}

class _DynamicFormPageState extends State<DynamicFormPage> with AutomaticKeepAliveClientMixin {
  // 存储动态表单数据的列表,可替换为自定义模型
  List<Map<String, String>> formList = [];

  @override
  bool get wantKeepAlive => true;

  @override
  Widget build(BuildContext context) {
    super.build(context); // 必须调用以触发保活逻辑
    return Scaffold(
      appBar: AppBar(title: const Text("动态表单")),
      body: ListView.builder(
        itemCount: formList.length,
        itemBuilder: (context, index) {
          return TextFormField(
            initialValue: formList[index]['content'],
            onChanged: (value) {
              setState(() {
                formList[index]['content'] = value;
              });
            },
          );
        },
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          setState(() {
            formList.add({'content': ''});
          });
        },
        child: const Icon(Icons.add),
      ),
    );
  }
}

方案2:全局状态管理(跨页面共享数据)

若需要在多个页面共享表单数据,或希望会话内页面重建后数据不丢失,可使用状态管理工具(如Riverpod、Provider)将数据存储在全局状态中,页面依赖状态渲染UI。

以Riverpod为例:

  1. 定义表单模型与状态管理类
// 表单数据模型
class FormItem {
  String content;
  FormItem({required this.content});
}

// 状态管理类
class FormListNotifier extends StateNotifier<List<FormItem>> {
  FormListNotifier() : super([]);

  // 添加新表单
  void addForm() {
    state = [...state, FormItem(content: '')];
  }

  // 更新表单内容
  void updateForm(int index, String content) {
    final updatedList = List<FormItem>.from(state);
    updatedList[index] = FormItem(content: content);
    state = updatedList;
  }
}

// 定义全局Provider
final formListProvider = StateNotifierProvider<FormListNotifier, List<FormItem>>((ref) {
  return FormListNotifier();
});
  1. 在动态表单页面中使用Provider:
class DynamicFormPage extends ConsumerWidget {
  const DynamicFormPage({super.key});

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final formList = ref.watch(formListProvider);
    return Scaffold(
      appBar: AppBar(title: const Text("动态表单")),
      body: ListView.builder(
        itemCount: formList.length,
        itemBuilder: (context, index) {
          return TextFormField(
            initialValue: formList[index].content,
            onChanged: (value) {
              ref.read(formListProvider.notifier).updateForm(index, value);
            },
          );
        },
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          ref.read(formListProvider.notifier).addForm();
        },
        child: const Icon(Icons.add),
      ),
    );
  }
}

方案3:本地持久化(永久留存,APP重启后仍保留)

如果需要APP重启后数据不丢失,需将表单数据持久化到本地存储,简单数据可用SharedPreferences,复杂模型推荐用Hive或Isar。

以Hive为例:

  1. 初始化Hive并定义模型Adapter:
// 先在pubspec.yaml添加依赖
// hive: ^2.2.3
// hive_flutter: ^1.1.0
// build_runner: ^2.4.4
// hive_generator: ^1.1.5

// 表单模型
@HiveType(typeId: 0)
class FormItem extends HiveObject {
  @HiveField(0)
  String content;

  FormItem({required this.content});
}

// 运行命令生成Adapter: flutter packages pub run build_runner build
  1. 在动态表单页面中读写本地数据:
class DynamicFormPage extends StatefulWidget {
  const DynamicFormPage({super.key});

  @override
  State<DynamicFormPage> createState() => _DynamicFormPageState();
}

class _DynamicFormPageState extends State<DynamicFormPage> {
  late Box<FormItem> formBox;
  List<FormItem> formList = [];

  @override
  void initState() {
    super.initState();
    // 打开Hive存储盒子
    formBox = Hive.box<FormItem>('form_box');
    // 从本地加载已有数据
    loadFormData();
  }

  void loadFormData() {
    setState(() {
      formList = formBox.values.toList();
    });
  }

  // 保存单个表单数据到本地
  void saveFormItem(int index, String content) {
    final formItem = FormItem(content: content);
    formBox.putAt(index, formItem);
  }

  // 添加新表单并保存到本地
  void addForm() {
    final newForm = FormItem(content: '');
    formBox.add(newForm);
    loadFormData();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text("动态表单")),
      body: ListView.builder(
        itemCount: formList.length,
        itemBuilder: (context, index) {
          return TextFormField(
            initialValue: formList[index].content,
            onChanged: (value) {
              saveFormItem(index, value);
            },
          );
        },
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: addForm,
        child: const Icon(Icons.add),
      ),
    );
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 22:30:49