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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 20:39:54