Flutter开发中如何从另一个自定义Widget中获取TextFormField的输入数据
实现方法
你已经使用了Flutter官方的Form组件配套全局GlobalKey,直接复用Form自带的表单提交能力即可实现需求,步骤如下:
步骤1:补全CustomGeneratedWidget的回调透传
首先修改CustomGeneratedWidget的组件定义,新增onSaved回调参数透传给内部的TextFormField,示例代码:
class CustomGeneratedWidget extends StatefulWidget { final Mywidget mywidget; // 新增onSaved回调参数 final ValueChanged<String?>? onSaved; const CustomGeneratedWidget(this.mywidget, {super.key, this.onSaved}); @override State<CustomGeneratedWidget> createState() => _CustomGeneratedWidgetState(); } // 内部TextFormField配置onSaved child: TextFormField( controller: textEditingController, obscureText: isPasswordField(widget.mywidget.key), keyboardType: customType(widget.mywidget.key), decoration: InputDecoration( labelText: widget.mywidget.label, border: const OutlineInputBorder() ), // 补全validator逻辑 validator: (value) { if (value == null || value.isEmpty) { return "请输入${widget.mywidget.label}"; } return null; }, // 绑定透传的onSaved回调 onSaved: widget.onSaved, )
记得在CustomGeneratedWidget的dispose生命周期中销毁textEditingController避免内存泄漏。
步骤2:在custom_form.dart中定义存储表单数据的容器
在custom_form.dart对应的State类中,定义一个Map用来存储所有动态表单项的数值,用每个Mywidget的key字段作为Map的键:
class CustomFormState extends State<CustomForm> { final _globalKey = GlobalKey<FormState>(); // 新增表单数据存储容器 final Map<String, dynamic> formData = {}; // 其余原有逻辑不变 }
步骤3:修改动态组件生成逻辑,绑定存储逻辑
修改generateWidgetFromType方法中Input类型组件的onSaved逻辑,把输入值存入对应key的位置,你也可以给CheckBox、DatePicker等其他组件也加相同逻辑统一收集数据:
Widget generateWidgetFromType(Mywidget mywidget) { switch (mywidget.type) { case "CheckBox": // 可参照Input逻辑添加onSaved回调收集复选框值 return GenerateCheckBox(mywidget); case "Input": return CustomGeneratedWidget(mywidget, // 把值存入formData对应key onSaved: (value) => formData[mywidget.key] = value); case "DatePicker": // 可参照Input逻辑添加onSaved回调收集日期值 return GenerateDatePicker(mywidget); default: return const Text("This type is not supported yet"); } }
步骤4:添加按钮点击事件中触发表单收集
在添加按钮的点击回调中,先调用Form的验证方法,验证通过后触发save方法即可完成所有表单项数据的收集:
void onAddButtonTap() { // 验证所有表单项合法性 if (_globalKey.currentState!.validate()) { // 触发所有表单项的onSaved回调,完成数据收集 _globalKey.currentState!.save(); // 此时formData中已经包含所有TextFormField的输入数据,可直接使用 debugPrint(formData.toString()); // 后续执行你的添加业务逻辑 } }
如果不想使用Form的save机制,你也可以在State中定义Map<String, TextEditingController> controllerMap,生成CustomGeneratedWidget时提前创建对应key的controller传入组件,点击按钮时直接遍历controllerMap取值即可,注意页面销毁时要遍历调用所有controller的dispose方法。
内容的提问来源于stack exchange,提问作者StormSpirite
相关产品推荐
相关产品推荐

