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

Flutter Autocomplete:fieldViewBuilder中onFieldSubmitted条件调用及长度更新问题

问题解决方法

你的问题根源在于optionsLength变量更新时未触发组件状态重建,且optionsViewBuilder的执行时机无法与输入变化实时同步,导致fieldViewBuilder始终读取旧值。以下是两种可行的解决方式:

方案一:实时计算匹配项数量(推荐)

直接在onFieldSubmitted中复用optionsBuilder的过滤逻辑,实时计算当前输入对应的匹配项数量,无需依赖外部变量:

class _MyAutocompleteState extends State<MyAutocomplete> {
  @override
  Widget build(BuildContext context) {
    return Autocomplete<String>(
      optionsBuilder: (TextEditingValue value) {
        return widget.holidayNamesList
            .where((element) => element.toLowerCase().contains(value.text.toLowerCase()));
      },
      optionsViewBuilder: (context, onSelected, myList) {
        // 保留原有选项视图实现
        return Material(
          child: ListView.builder(
            itemCount: myList.length,
            itemBuilder: (context, index) {
              final option = myList.elementAt(index);
              return ListTile(
                title: Text(option),
                onTap: () => onSelected(option),
              );
            },
          ),
        );
      },
      fieldViewBuilder: (context, controller, node, onFieldSubmitted) {
        return TextFormField(
          controller: controller,
          focusNode: node,
          onFieldSubmitted: (String value) {
            onFieldSubmitted();
            // 实时计算当前输入对应的匹配项数量
            final matchedCount = widget.holidayNamesList
                .where((element) => element.toLowerCase().contains(value.toLowerCase()))
                .length;
            if (matchedCount == 0) {
              widget.setSelectedHoliday(selectedName: value);
            }
          },
          // 其他TextFormField配置项
        );
      },
    );
  }
}

这种方式规避了状态不同步问题,逻辑直接可靠,无需额外状态管理开销。

方案二:通过setState更新optionsLength

如果坚持使用optionsLength变量,需在赋值时调用setState触发组件重建,确保fieldViewBuilder能获取最新值:

class _MyAutocompleteState extends State<MyAutocomplete> {
  int? optionsLength;

  @override
  Widget build(BuildContext context) {
    return Autocomplete<String>(
      optionsBuilder: (TextEditingValue value) {
        return widget.holidayNamesList
            .where((element) => element.toLowerCase().contains(value.text.toLowerCase()));
      },
      optionsViewBuilder: (context, onSelected, myList) {
        // 赋值时调用setState更新状态
        setState(() {
          optionsLength = myList.length;
        });
        // 保留原有选项视图实现
        return Material(
          child: ListView.builder(
            itemCount: myList.length,
            itemBuilder: (context, index) {
              final option = myList.elementAt(index);
              return ListTile(
                title: Text(option),
                onTap: () => onSelected(option),
              );
            },
          ),
        );
      },
      fieldViewBuilder: (context, controller, node, onFieldSubmitted) {
        return TextFormField(
          controller: controller,
          focusNode: node,
          onFieldSubmitted: (String value) {
            onFieldSubmitted();
            if (optionsLength == 0) {
              widget.setSelectedHoliday(selectedName: value);
            }
          },
          // 其他TextFormField配置项
        );
      },
    );
  }
}

注意:该方式会因setState触发组件频繁重建,性能略逊于方案一,仅在有其他场景需要复用optionsLength时考虑使用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 17:02:45