would need some advice. I try to implement showSearch in appBar and have a LocationSearchDelegate() class with SearchDelegate in it. There is no error in my code, but when I run it and click on the search button it shows:
══╡ EXCEPTION CAUGHT BY GESTURE ╞═══════════════════════════════════════════════════════════════════
The following assertion was thrown while handling a gesture:
Navigator operation requested with a context that does not include a Navigator.
The context used to push or pop routes from the Navigator must be that of a widget that is a
descendant of a Navigator widget.
here’s my code in main.dart
class MainApp extends StatelessWidget {
const MainApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text("Raincheck"),
actions: [
IconButton(
icon: const Icon(Icons.search),
onPressed: () {
showSearch(
context: context,
delegate: LocationSearchDelegate(),
);
},
),
// IconButton(
// onPressed: () {},
// icon: const Icon(Icons.settings),
// )
],
),
body: const Center(
child: HomePage(),
),
),
);
}
}
and here is my LocationSearchDelegate()
class LocationSearchDelegate extends SearchDelegate {
List<String> suggestions = [
"USA",
"China",
"Australia",
];
@override
List<Widget>? buildActions(BuildContext context) => [
IconButton(
icon: const Icon(Icons.clear),
onPressed: () {
query = "";
})
];
@override
Widget? buildLeading(BuildContext context) => IconButton(
icon: const Icon(Icons.arrow_back),
onPressed: () => close(context, null));
@override
Widget buildResults(BuildContext context) {
List<String> matchQuery = [];
for (var suggestion in suggestions) {
if (suggestion.toLowerCase().contains(query.toLowerCase())) {
matchQuery.add(suggestion);
}
}
return ListView.builder(
itemCount: matchQuery.length,
itemBuilder: (context, index) {
var result = matchQuery[index];
return ListTile(
title: Text(result),
);
},
);
}
@override
Widget buildSuggestions(BuildContext context) {
return ListView.builder(
itemCount: suggestions.length,
itemBuilder: (context, index) {
final suggestion = suggestions[index];
return ListTile(
title: Text(suggestion),
onTap: () {
query = suggestion;
},
);
},
);
}
}
2
Answers
Separate Your code like this, then your issue will be fixed.I assume this is happening because you are using the Material app context instead of the home context
I don’t know what is on your homepage, if its a layout without using scaffold I m suggesting that emove that and move all the widgets to the homebody
There’s a very simple answer to what is happening in your code, and it is something that is pretty fundamental to how flutter works.
Let’s take a look at your code:
The issue here is that you’re passing MainApp’s context to
showSearch
. Let’s take a quick look atshowSearch
‘s implementation:So… in that, they’re calling
Navigator.of(context,...)
. Now back to your code – I’m going to show you the tree of widgets created (-Navigator- and -WidgetApp- (among others) are created implicitly by MaterialApp which is why I’m using the-
):So, because the context being passed to
showSearch
is directed toMainApp
, searching forNavigator
on it will fail. And just to be clear, WidgetApp and Navigator are created implicitly within MaterialApp. But anyways, what do we need to do? Make sure that the context being passed toshowSearch
is below the navigator.There’s two easy ways to do this. The first would be to split the page from the app, which is honestly a better way of building things anyways. This would mean something like this:
The second way would be to use a builder:
Either of those solutions make sure that the
context
orsubContext
being used by theshowSearch
function are actually below theNavigator
‘s context.