Flutter中RawAutocomplete不显示Firestore来源选项问题排查
RawAutocomplete不显示建议选项的排查与修复
核心问题排查
Provider类型不匹配
父组件中FutureProvider的泛型是List<jeUserWithID>,但Consumer监听的是List<User>,类型不匹配导致Consumer无法获取Firestore加载的真实数据,始终拿到初始空列表。未传递RawAutocomplete核心依赖参数
fieldViewBuilder中未使用组件提供的textEditingController、focusNode和onFieldSubmitted,导致RawAutocomplete无法监听输入变化、焦点状态,无法触发选项展示逻辑。空值处理隐患
element.UserInfo.name!使用强制非空断言,若存在name为null的用户数据,会直接导致筛选逻辑异常。
修复后的代码实现
1. 父组件修正Provider类型
// 修正泛型类型,与Consumer监听的List<User>保持一致 MultiProvider( providers: [ FutureProvider<List<User>>(create: (_) => fetchClientsFromBase(), initialData: []), ], child: // ... 原有子组件结构 );
2. ClientSearchOrAdd组件完整修复
import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'dataStructs.dart'; import 'utils.dart'; class ClientSearchOrAdd extends StatefulWidget { final TextEditingController clientNameController; const ClientSearchOrAdd({super.key, required this.clientNameController}); @override State<ClientSearchOrAdd> createState() => _ClientSearchOrAddState(); } class _ClientSearchOrAddState extends State<ClientSearchOrAdd> { @override Widget build(BuildContext context) { return Consumer<List<User>>( builder: (BuildContext context, List<User> userList, _) { return RawAutocomplete<String>( // 选项选中后同步外部控制器 onSelected: (String selection) { widget.clientNameController.text = selection; }, optionsBuilder: (TextEditingValue textEditingValue) { // 空输入时返回空列表,避免全量展示 if (textEditingValue.text.isEmpty) return const []; return userList .where((element) => // 先判断name不为null,再执行筛选逻辑 element.userInfo.name != null && element.userInfo.name!.toLowerCase().contains(textEditingValue.text.toLowerCase())) .map((e) => e.userInfo.name!) .toList(); }, optionsViewBuilder: ( BuildContext context, AutocompleteOnSelected<String> onSelected, Iterable<String> options, ) { return Align( alignment: Alignment.topLeft, child: Material( elevation: 4.0, child: SizedBox( height: 292.0, child: ListView.builder( padding: const EdgeInsets.all(8.0), itemCount: options.length, itemBuilder: (BuildContext context, int index) { final String option = options.elementAt(index); return ListTile( title: Text(option), onTap: () => onSelected(option), ); }, ), ), ), ); }, fieldViewBuilder: ( BuildContext context, TextEditingController autocompleteController, FocusNode focusNode, VoidCallback onFieldSubmitted, ) { // 同步RawAutocomplete控制器与外部控制器的文本内容 autocompleteController.text = widget.clientNameController.text; autocompleteController.addListener(() { widget.clientNameController.text = autocompleteController.text; }); return TextFormField( controller: autocompleteController, // 使用组件内置控制器 focusNode: focusNode, // 传递焦点节点 onFieldSubmitted: (_) => onFieldSubmitted(), // 传递提交回调 inputFormatters: [FirstLetterUpperCaseFormatter()], decoration: Utils.textFormFieldStyle( labelTextStr: 'Client Name', hintTextStr: 'Enter client name'), ); }, ); }); } }
关键修复说明
- 类型一致性:确保Provider提供的数据类型与Consumer监听的类型完全匹配,才能正确获取Firestore异步加载的数据。
- 核心参数传递:RawAutocomplete的
textEditingController和focusNode是组件感知输入变化、控制选项显示的核心,必须在fieldViewBuilder中传递给TextFormField。 - 空值安全:筛选逻辑中先判断
name不为null,避免强制解包导致的崩溃,同时空输入时返回空列表优化体验。 - 控制器同步:通过监听内置控制器的变化,同步外部传入的控制器文本,保证外部逻辑与组件内部状态一致。
内容的提问来源于stack exchange,提问作者pbs
相关产品推荐
相关产品推荐

