'Why AutoCompleteTextField is not showing any suggestion in Flutter?
I am new to Flutter and currently working on a project where I need to show user a list of matched members so that a user can easily select one of them. For that I use AutoCompleteTextField. It is working fine as long as provided by already fetched list of members to it's suggestion property. But I wonder, why it's not working when I put it under BlocBuilder. Event hits on textChanged method and the state also returns a list but the suggestions are invisible.
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),
);
}
Solution 1:[1]
Use the flutter_typeahead package which works well with flutter bloc
Now, come to the bloc side you don't need to wrap your autocomplete widget with blocbuilder cause if you do so, the bloc will always repaint the widget whenever an event fires. so in your case when you are typing in the text box, event fires and bloc rebuild the widget and because of that suggestion don't show up and even if you see suggestion they will be gone once the corresponding bloc state occurs and rebuild the widget
the recommended solution would be seen below
Don't add any state to get suggestions just return the result or records from event as below. (below function added to Cubit file)
Future<List<Item>> getProductItemsBySearchString(String item) async {
return await itemRepository.getItemsByName(item);
}
as you can see above I am returning item records directly from the getProductItemsBySearchString() event method (no bloc state)
Then use It like below
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
},
);
}
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 |