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
相关产品推荐
相关产品推荐

