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

Flutter中如何结合动态表单使用SharedPreference

解决方案

一、选择本地存储方案

推荐用shared_preferences包,轻量且适合存储键值对类型的表单数据;如果表单结构复杂,也可以用hive(NoSQL本地数据库),这里以shared_preferences为例。

1. 引入依赖

在pubspec.yaml中添加:

dependencies:
  flutter:
    sdk: flutter
  shared_preferences: ^2.2.2

二、动态表单的数据存储与读取逻辑

核心思路:给每个动态生成的表单字段分配唯一key,用这个key作为存储的键,对应字段的输入值作为值;启动时通过这个key读取对应值,填充到输入框的控制器中。

1. 维护表单控制器与字段标识

假设动态表单的字段信息存在一个列表中,每个字段包含id(唯一key)、label等信息:

// 示例:动态表单字段配置
List<Map<String, String>> formFields = [
  {'id': 'username', 'label': '用户名'},
  {'id': 'email', 'label': '邮箱'},
  {'id': 'phone', 'label': '手机号'},
];

// 存储每个字段的TextEditingController,用字段id作为key
Map<String, TextEditingController> controllers = {};

// 初始化控制器
void initControllers() {
  for (var field in formFields) {
    controllers[field['id']!] = TextEditingController();
  }
}

2. 保存表单数据

可以在用户输入时实时保存,或者在表单提交时批量保存:

import 'package:shared_preferences/shared_preferences.dart';

// 保存单个字段的值
Future<void> saveFieldValue(String fieldId, String value) async {
  final prefs = await SharedPreferences.getInstance();
  await prefs.setString(fieldId, value);
}

// 批量保存所有表单数据
Future<void> saveAllFormData() async {
  final prefs = await SharedPreferences.getInstance();
  for (var entry in controllers.entries) {
    await prefs.setString(entry.key, entry.value.text);
  }
}

3. 启动时加载并填充数据

在initState中读取存储的数据,赋值给对应控制器:

@override
void initState() {
  super.initState();
  initControllers();
  loadSavedFormData();
}

Future<void> loadSavedFormData() async {
  final prefs = await SharedPreferences.getInstance();
  for (var field in formFields) {
    String? savedValue = prefs.getString(field['id']!);
    if (savedValue != null) {
      controllers[field['id']!].text = savedValue;
    }
  }
}

4. 动态生成表单组件

用ListView或Column遍历字段配置,生成TextField:

@override
Widget build(BuildContext context) {
  return Scaffold(
    appBar: AppBar(title: const Text('动态表单')),
    body: Padding(
      padding: const EdgeInsets.all(16.0),
      child: Column(
        children: formFields.map((field) {
          return TextField(
            controller: controllers[field['id']!],
            decoration: InputDecoration(labelText: field['label']),
            onChanged: (value) {
              // 实时保存输入值
              saveFieldValue(field['id']!, value);
            },
          );
        }).toList(),
      ),
    ),
    floatingActionButton: FloatingActionButton(
      onPressed: saveAllFormData,
      child: const Icon(Icons.save),
    ),
  );
}

三、注意事项

  • 如果表单字段是动态新增/删除的,要同步维护formFields列表和controllers,确保每个字段的id唯一;
  • 若需要存储复杂结构的表单数据(比如数组、对象),可以将数据序列化为JSON字符串后存储,读取时再反序列化;
  • 记得在页面销毁时 dispose 所有控制器,避免内存泄漏:
@override
void dispose() {
  controllers.values.forEach((controller) => controller.dispose());
  super.dispose();
}

内容的提问来源于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 23:20:40