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
相关产品推荐
相关产品推荐

