为什么 AutoCompleteTextField 在 Flutter 中没有显示任何建议?
Why AutoCompleteTextField is not showing any suggestion in Flutter?
我是 Flutter 的新手,目前正在做一个项目,我需要向用户显示匹配成员的列表,以便用户可以轻松地 select 其中之一。为此,我使用 AutoCompleteTextField。只要已经获取的成员列表提供给它的建议 属性,它就可以正常工作。但我想知道,为什么当我把它放在 BlocBuilder 下时它不起作用。事件命中 textChanged 方法,状态也是 returns 列表,但建议是不可见的。
Widget autoCompleteSearchBar() {
return BlocBuilder<OrderInfoBloc, MyOrderInfoStates>(
builder: (context, state) {
return AutoCompleteTextField<Member>(
clearOnSubmit: false,
style: TextStyle(
color: Colors.black,
fontSize: 16,
),
decoration: InputDecoration(
hintText: 'Search Member Here..',
border: InputBorder.none,
suffixIcon: IconButton(
icon: Icon(Icons.cancel),
iconSize: 20,
color: Colors.yellow[700],
onPressed: () {
_autoCompleteController.text = "";
},
),
contentPadding: EdgeInsets.fromLTRB(10, 30, 10, 20),
hintStyle: TextStyle(color: Colors.grey),
),
keyboardType: TextInputType.text,
controller: _autoCompleteController,
textChanged: (value) {
context.read<OrderInfoBloc>().add(SearchTextChanged(text: value));
},
itemSubmitted: (item) async {
_autoCompleteController.text = state.radioGroupValue == 'By Code'
? item.memberNo
: item.memberName;
context.read<OrderInfoBloc>().add(SelectedMember(member: item));
},
key: _key,
suggestions: state.membersList,
itemBuilder: (context, item) {
print(item);
// return state.radioGroupValue == 'By Code'
// ? autoCompleteSearchBarRow(
// item: item.memberNo, icon: Icon(Icons.person))
// : autoCompleteSearchBarRow(
// item: item.memberName, icon: Icon(Icons.person));
return autoCompleteSearchBarRow(
item: item.memberNo, icon: Icon(Icons.person));
},
itemFilter: (item, query) {
print(query);
// bool _itemFilter;
// if (_autoCompleteController.text.isNotEmpty) {
// _itemFilter = state.radioGroupValue == 'By Code'
// ? item.memberNo
// .toLowerCase()
// .startsWith(query.toLowerCase())
// : item.memberName
// .toLowerCase()
// .startsWith(query.toLowerCase());
// } else {
// _autoCompleteController.text = '';
// _itemFilter = false;
// }
// return _itemFilter;
return item.memberNo.toLowerCase().startsWith(query.toLowerCase());
},
itemSorter: (a, b) {
// return state.radioGroupValue == 'By Code'
// ? a.memberNo.compareTo(b.memberNo.toLowerCase())
// : a.memberName.compareTo(b.memberName.toLowerCase());
print(b);
return a.memberNo.compareTo(b.memberNo.toLowerCase());
},
);
}
);
}
Widget autoCompleteSearchBarRow(
{@required String item, @required Icon icon}) {
return ListTile(
leading: icon,
title: Text(item),
);
}
使用与 flutter bloc 配合良好的 flutter_typeahead 包
现在,来到集团方面,您不需要使用 blocbuilder 包装您的自动完成小部件,因为如果您这样做,集团将始终在事件触发时重新绘制小部件。因此,在您的情况下,当您在文本框中键入内容时,事件会触发并 bloc 重建小部件,并且由于该建议不会显示,即使您看到建议,一旦相应的 bloc 状态发生并重建小部件,它们也会消失
推荐的解决方案如下所示
不要添加任何状态以获得建议,仅 return 事件的结果或记录如下。 (以下功能已添加到 Cubit 文件中)
Future<List<Item>> getProductItemsBySearchString(String item) async {
return await itemRepository.getItemsByName(item);
}
正如您在上面看到的那样,我 return 直接从 getProductItemsBySearchString() 事件方法(无 bloc 状态)获取商品记录
然后像下面这样使用它
class ItemScreen extends StatelessWidget {
// then you can call bloc event in function as below
Future<List<Item>> getItemSuggestionsList(
BuildContext context, String text) async {
final bloc = context.read<ItemCubit>();
List<Item> data = await bloc.getProductItemsBySearchString(text);
if (data != null) {
return data;
} else {
return null;
}
}
@override
Widget build(BuildContext context) {
return TypeAheadField(
getImmediateSuggestions: true,
textFieldConfiguration: TextFieldConfiguration(
controller: _itemEditingController,
autofocus: false),
suggestionsCallback: (pattern) {
// call the function to get suggestions based on text entered
return getItemSuggestionsList(context, pattern);
},
itemBuilder: (context, suggestion) {
// show suggection list
return Padding(
padding: const EdgeInsets.all(8.0),
child: ListTile(
title: Text(suggestion.name),
trailing: Text(
'Item Code: ${suggestion.code}',
),
),
);
},
onSuggestionSelected: (suggestion) {
// get selected suggesion
},
);
}
}
我是 Flutter 的新手,目前正在做一个项目,我需要向用户显示匹配成员的列表,以便用户可以轻松地 select 其中之一。为此,我使用 AutoCompleteTextField。只要已经获取的成员列表提供给它的建议 属性,它就可以正常工作。但我想知道,为什么当我把它放在 BlocBuilder 下时它不起作用。事件命中 textChanged 方法,状态也是 returns 列表,但建议是不可见的。
Widget autoCompleteSearchBar() {
return BlocBuilder<OrderInfoBloc, MyOrderInfoStates>(
builder: (context, state) {
return AutoCompleteTextField<Member>(
clearOnSubmit: false,
style: TextStyle(
color: Colors.black,
fontSize: 16,
),
decoration: InputDecoration(
hintText: 'Search Member Here..',
border: InputBorder.none,
suffixIcon: IconButton(
icon: Icon(Icons.cancel),
iconSize: 20,
color: Colors.yellow[700],
onPressed: () {
_autoCompleteController.text = "";
},
),
contentPadding: EdgeInsets.fromLTRB(10, 30, 10, 20),
hintStyle: TextStyle(color: Colors.grey),
),
keyboardType: TextInputType.text,
controller: _autoCompleteController,
textChanged: (value) {
context.read<OrderInfoBloc>().add(SearchTextChanged(text: value));
},
itemSubmitted: (item) async {
_autoCompleteController.text = state.radioGroupValue == 'By Code'
? item.memberNo
: item.memberName;
context.read<OrderInfoBloc>().add(SelectedMember(member: item));
},
key: _key,
suggestions: state.membersList,
itemBuilder: (context, item) {
print(item);
// return state.radioGroupValue == 'By Code'
// ? autoCompleteSearchBarRow(
// item: item.memberNo, icon: Icon(Icons.person))
// : autoCompleteSearchBarRow(
// item: item.memberName, icon: Icon(Icons.person));
return autoCompleteSearchBarRow(
item: item.memberNo, icon: Icon(Icons.person));
},
itemFilter: (item, query) {
print(query);
// bool _itemFilter;
// if (_autoCompleteController.text.isNotEmpty) {
// _itemFilter = state.radioGroupValue == 'By Code'
// ? item.memberNo
// .toLowerCase()
// .startsWith(query.toLowerCase())
// : item.memberName
// .toLowerCase()
// .startsWith(query.toLowerCase());
// } else {
// _autoCompleteController.text = '';
// _itemFilter = false;
// }
// return _itemFilter;
return item.memberNo.toLowerCase().startsWith(query.toLowerCase());
},
itemSorter: (a, b) {
// return state.radioGroupValue == 'By Code'
// ? a.memberNo.compareTo(b.memberNo.toLowerCase())
// : a.memberName.compareTo(b.memberName.toLowerCase());
print(b);
return a.memberNo.compareTo(b.memberNo.toLowerCase());
},
);
}
);
}
Widget autoCompleteSearchBarRow(
{@required String item, @required Icon icon}) {
return ListTile(
leading: icon,
title: Text(item),
);
}
使用与 flutter bloc 配合良好的 flutter_typeahead 包
现在,来到集团方面,您不需要使用 blocbuilder 包装您的自动完成小部件,因为如果您这样做,集团将始终在事件触发时重新绘制小部件。因此,在您的情况下,当您在文本框中键入内容时,事件会触发并 bloc 重建小部件,并且由于该建议不会显示,即使您看到建议,一旦相应的 bloc 状态发生并重建小部件,它们也会消失
推荐的解决方案如下所示
不要添加任何状态以获得建议,仅 return 事件的结果或记录如下。 (以下功能已添加到 Cubit 文件中)
Future<List<Item>> getProductItemsBySearchString(String item) async {
return await itemRepository.getItemsByName(item);
}
正如您在上面看到的那样,我 return 直接从 getProductItemsBySearchString() 事件方法(无 bloc 状态)获取商品记录
然后像下面这样使用它
class ItemScreen extends StatelessWidget {
// then you can call bloc event in function as below
Future<List<Item>> getItemSuggestionsList(
BuildContext context, String text) async {
final bloc = context.read<ItemCubit>();
List<Item> data = await bloc.getProductItemsBySearchString(text);
if (data != null) {
return data;
} else {
return null;
}
}
@override
Widget build(BuildContext context) {
return TypeAheadField(
getImmediateSuggestions: true,
textFieldConfiguration: TextFieldConfiguration(
controller: _itemEditingController,
autofocus: false),
suggestionsCallback: (pattern) {
// call the function to get suggestions based on text entered
return getItemSuggestionsList(context, pattern);
},
itemBuilder: (context, suggestion) {
// show suggection list
return Padding(
padding: const EdgeInsets.all(8.0),
child: ListTile(
title: Text(suggestion.name),
trailing: Text(
'Item Code: ${suggestion.code}',
),
),
);
},
onSuggestionSelected: (suggestion) {
// get selected suggesion
},
);
}
}