I am using the package flutter_bloc
for state management. I want to create a search screen, and found the showSearch
Flutter function, and have been having issues providing a BLoC
instance to the ListView
my SearchDelegate
implementation creates. I finally made it work, but would like to ask what the best way of doing this is. Here is the code (excerpts, starting from a button that is placed in an AppBar
within a Scaffold
):
class ItemSearchButton extends StatelessWidget {
@override
Widget build(BuildContext context) {
return IconButton(
icon: Icon(Icons.search),
onPressed: () {
final itemListBloc = context.bloc<ItemListBloc>();
showSearch(
context: context,
delegate: _ItemSearchDelegate(itemListBloc),
);
},
);
}
}
class _ItemSearchDelegate extends SearchDelegate<String> {
final ItemListBloc itemListBloc;
_ItemSearchDelegate(this.itemListBloc);
// other overridden methods
@override
Widget buildSuggestions(BuildContext context) {
return BlocProvider.value(
value: itemListBloc,
child: ItemListWidget(),
);
}
}
Basically, the context that invokes the showSearch
method has the correct BLoC instance, but it is not available within my SearchDelegate
implementation, unless I re-provide it again explicitly in buildSuggestions
.
Why is the BLoC not available by default? The showSearch
function internally pushes a new Navigator
Route
, is this the issue?
What is the canonical way of dealing with things like this?
In the end it works as intended - the pushed route has a new context that is not a child of a context that has my BLoC, it is a child of the Navigator
. The solution is to either do what I did initially - pass the BLoC explicitly as constructor argument - or make sure the Navigator
context has the BLoCs, which is what I eventually did; to do this, make sure the Navigator
is a child of the (Multi)BlocProvider
.