Flutter FormBuilder:同一变量下如何单独启用关联文本字段
解决思路与实现方案
问题根源在于你用了单个布尔值isEnabled,操作任意复选框组都会覆盖这个值,导致两个文本框同时响应。要在保留同一个变量的前提下实现独立控制,你可以把isEnabled的类型从布尔值改成能区分不同文本框的类型,比如枚举、映射表,以下是两种可行方案:
方案1:使用枚举类型
把isEnabled定义为枚举,明确标记当前启用的文本框,逻辑清晰直观:
import 'package:flutter/material.dart'; import 'package:flutter_form_builder/flutter_form_builder.dart'; // 定义枚举,标记可启用的文本框 enum EnabledTextField { none, textField1, textField2 } class MyForm extends StatefulWidget { const MyForm({super.key}); @override _MyFormState createState() => _MyFormState(); } class _MyFormState extends State<MyForm> { final _formKey = GlobalKey<FormBuilderState>(); // 保留isEnabled变量,类型改为枚举 EnabledTextField isEnabled = EnabledTextField.none; @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('My Form'), ), body: Padding( padding: const EdgeInsets.all(16.0), child: FormBuilder( key: _formKey, child: Column( children: [ FormBuilderCheckboxGroup( name: 'checkboxGroup1', options: const [ FormBuilderFieldOption(value: 'option1', child: Text('Option 1')), FormBuilderFieldOption(value: 'option2', child: Text('Option 2')), FormBuilderFieldOption(value: 'option3', child: Text('Option 3')), ], onChanged: (value) { setState(() { final hasOption3 = value?.contains('option3') ?? false; // 根据选择设置对应的枚举值 isEnabled = hasOption3 ? EnabledTextField.textField1 : EnabledTextField.none; }); }, ), const SizedBox(height: 16), FormBuilderTextField( // 判断当前枚举是否匹配自身 enabled: isEnabled == EnabledTextField.textField1, name: 'textField1', decoration: const InputDecoration(labelText: 'Text Field 1'), ), const SizedBox(height: 16), FormBuilderCheckboxGroup( name: 'checkboxGroup2', options: const [ FormBuilderFieldOption(value: 'option4', child: Text('Option 4')), FormBuilderFieldOption(value: 'option5', child: Text('Option 5')), FormBuilderFieldOption(value: 'option6', child: Text('Option 6')), ], onChanged: (value) { setState(() { final hasOption6 = value?.contains('option6') ?? false; isEnabled = hasOption6 ? EnabledTextField.textField2 : EnabledTextField.none; }); }, ), const SizedBox(height: 16), FormBuilderTextField( enabled: isEnabled == EnabledTextField.textField2, name: 'textField2', decoration: const InputDecoration(labelText: 'Text Field 2'), ), ], ), ), ), ); } }
方案2:使用映射表(Map)
如果需要支持更多文本框,用Map更灵活,同样只需要一个isEnabled变量:
import 'package:flutter/material.dart'; import 'package:flutter_form_builder/flutter_form_builder.dart'; class MyForm extends StatefulWidget { const MyForm({super.key}); @override _MyFormState createState() => _MyFormState(); } class _MyFormState extends State<MyForm> { final _formKey = GlobalKey<FormBuilderState>(); // 保留isEnabled变量,类型为Map,存储每个文本框的启用状态 Map<String, bool> isEnabled = { 'textField1': false, 'textField2': false, }; @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('My Form'), ), body: Padding( padding: const EdgeInsets.all(16.0), child: FormBuilder( key: _formKey, child: Column( children: [ FormBuilderCheckboxGroup( name: 'checkboxGroup1', options: const [ FormBuilderFieldOption(value: 'option1', child: Text('Option 1')), FormBuilderFieldOption(value: 'option2', child: Text('Option 2')), FormBuilderFieldOption(value: 'option3', child: Text('Option 3')), ], onChanged: (value) { setState(() { // 只修改textField1的状态,不影响其他 isEnabled['textField1'] = value?.contains('option3') ?? false; }); }, ), const SizedBox(height: 16), FormBuilderTextField( enabled: isEnabled['textField1']!, name: 'textField1', decoration: const InputDecoration(labelText: 'Text Field 1'), ), const SizedBox(height: 16), FormBuilderCheckboxGroup( name: 'checkboxGroup2', options: const [ FormBuilderFieldOption(value: 'option4', child: Text('Option 4')), FormBuilderFieldOption(value: 'option5', child: Text('Option 5')), FormBuilderFieldOption(value: 'option6', child: Text('Option 6')), ], onChanged: (value) { setState(() { // 只修改textField2的状态,不影响其他 isEnabled['textField2'] = value?.contains('option6') ?? false; }); }, ), const SizedBox(height: 16), FormBuilderTextField( enabled: isEnabled['textField2']!, name: 'textField2', decoration: const InputDecoration(labelText: 'Text Field 2'), ), ], ), ), ), ); } }
方案说明
- 枚举方案适合固定数量的文本框场景,逻辑更直观;
- 映射表方案扩展性更强,后续新增文本框只需在Map中添加对应键值对即可。
两种方案都保留了isEnabled变量,且操作任意复选框组只会控制关联的文本框,不会互相影响。
内容的提问来源于stack exchange,提问作者kalibear
相关产品推荐
相关产品推荐

