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

Flutter技术问题:如何根据用户选择动态添加新TextField?

问题:选择指定选项后动态添加TextField

刚接触Flutter,想实现选择某个选项后动态添加新的TextField,但尝试后没成功,不知道问题出在哪。

我的完整代码

SelectFieldBloc selectFieldBloc = SelectFieldBloc(
                name: question.name,
                toJson: (option) => option?.optionText,
                validators: question.validation != null
                    ? [
                        (input) {
                          if (input != null) {
                            if (input is Option) {
                              Option option = input;
                              return inspectionValidator.inspect(
                                  option.optionText, question.validation);
                            } else if (input is SubOption) {
                              SubOption option = input;
                              return inspectionValidator.inspect(
                                  option.optionText, question.validation);
                            }
                          } else {
                            return inspectionValidator.inspect(
                                input, question.validation);
                          }
                        }
                      ]
                    : null,
                items: question.option);
            fieldBloc = selectFieldBloc;
            List<Widget> widgets = [];
            fieldBloc.onValueChanges(onData: (previous, current) async* {
              print(current.value?.optionText);
              if (current.value?.optionText == "Cultivated") {
                widgets.add(
                  TextFormField(
                    decoration: const InputDecoration(
                      border: UnderlineInputBorder(),
                      labelText: 'Enter your username',
                    ),
                  ),
                );
              }
            });
          }
          addFieldBloc(
            step: question.formId! - 1,
            fieldBloc: fieldBloc,
          );

核心尝试代码

fieldBloc = selectFieldBloc;
List<Widget> widgets = [];
fieldBloc.onValueChanges(onData: (previous, current) async* {
  print(current.value?.optionText);
  if (current.value?.optionText == "Cultivated") {
    widgets.add(
      TextFormField(
        decoration: const InputDecoration(
          border: UnderlineInputBorder(),
          labelText: 'Enter your username',
        ),
      ),
    );
  }

问题原因

当前写法有两个核心问题:

  1. 直接修改局部List<Widget>不会触发Flutter的UI重建,就算添加了TextField,界面也不会更新。
  2. widgets是局部变量,没有和页面状态绑定,无法被渲染到界面上。

解决方法

因为你用了flutter_bloc的SelectFieldBloc,可以通过BlocBuilder监听状态变化,动态构建UI:

实现代码示例

class YourPage extends StatefulWidget {
  const YourPage({super.key});

  @override
  State<YourPage> createState() => _YourPageState();
}

class _YourPageState extends State<YourPage> {
  late SelectFieldBloc selectFieldBloc;

  @override
  void initState() {
    super.initState();
    // 初始化SelectFieldBloc
    selectFieldBloc = SelectFieldBloc(
      name: question.name,
      toJson: (option) => option?.optionText,
      validators: question.validation != null
          ? [
              (input) {
                if (input != null) {
                  if (input is Option) {
                    Option option = input;
                    return inspectionValidator.inspect(
                        option.optionText, question.validation);
                  } else if (input is SubOption) {
                    SubOption option = input;
                    return inspectionValidator.inspect(
                        option.optionText, question.validation);
                  }
                } else {
                  return inspectionValidator.inspect(
                      input, question.validation);
                }
              }
            ]
          : null,
      items: question.option,
    );
    addFieldBloc(
      step: question.formId! - 1,
      fieldBloc: selectFieldBloc,
    );
  }

  @override
  void dispose() {
    selectFieldBloc.close();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: BlocBuilder<SelectFieldBloc, SelectFieldBlocState>(
        bloc: selectFieldBloc,
        builder: (context, state) {
          // 基础选择组件(替换成你实际使用的选择组件)
          final selectWidget = YourSelectFieldWidget(fieldBloc: selectFieldBloc);
          
          // 动态生成额外TextField
          List<Widget> dynamicWidgets = [];
          if (state.value?.optionText == "Cultivated") {
            dynamicWidgets.add(
              TextFormField(
                decoration: const InputDecoration(
                  border: UnderlineInputBorder(),
                  labelText: 'Enter your username',
                ),
              ),
            );
          }

          return Column(
            children: [
              selectWidget,
              ...dynamicWidgets,
            ],
          );
        },
      ),
    );
  }
}

关键说明

  • 用BlocBuilder监听SelectFieldBloc的状态变化,每次状态更新时自动重建UI,实现动态渲染。
  • 不需要手动维护widgets列表,直接在builder中根据当前状态判断是否添加TextField。
  • 记得在dispose中关闭Bloc,避免内存泄漏。

内容的提问来源于stack exchange,提问作者Priyanka Shakya

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 00:44:57