Flutter中正确使用SearchDelegate及Navigator上下文错误修复
问题原因与解决方法
错误根源
这个错误的核心是:你调用showSearch()时传入的context,没有关联到包含Navigator的Widget树节点。
Flutter中,MaterialApp(或CupertinoApp)会在内部自动创建Navigator,但只有当你的context属于MaterialApp的子Widget树时,才能访问到这个Navigator。如果你的context是MaterialApp本身或者它的直接父节点的context,就会触发该错误。
解决方法
方法1:用Builder组件包裹需要调用搜索的部分
Builder会提供一个属于子Widget树的context,让你能正常访问Navigator:
void main() => runApp(MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( home: Builder( builder: (context) => Scaffold( appBar: AppBar( title: const Text('Demo'), actions: [ IconButton( icon: const Icon(Icons.search), onPressed: () { showSearch(context: context, delegate: _SearchDelegate()); }, ), ], ), floatingActionButton: FloatingActionButton( onPressed: () { showSearch(context: context, delegate: _SearchDelegate()); }, child: const Icon(Icons.search), ), ), ), ); } } class _SearchDelegate extends SearchDelegate { @override List<Widget>? buildActions(BuildContext context) => []; @override Widget? buildLeading(BuildContext context) => null; @override Widget buildResults(BuildContext context) => const SizedBox(); @override Widget buildSuggestions(BuildContext context) => const SizedBox(); }
方法2:将主页抽成独立Widget
把主页内容从MaterialApp的build方法中分离出来,独立Widget的context天然属于MaterialApp的子树:
void main() => runApp(const MyApp()); class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return const MaterialApp( home: HomePage(), ); } } class HomePage extends StatelessWidget { const HomePage({super.key}); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('Demo'), actions: [ IconButton( icon: const Icon(Icons.search), onPressed: () { showSearch(context: context, delegate: _SearchDelegate()); }, ), ], ), floatingActionButton: FloatingActionButton( onPressed: () { showSearch(context: context, delegate: _SearchDelegate()); }, child: const Icon(Icons.search), ), ); } } class _SearchDelegate extends SearchDelegate { @override List<Widget>? buildActions(BuildContext context) => []; @override Widget? buildLeading(BuildContext context) => null; @override Widget buildResults(BuildContext context) => const SizedBox(); @override Widget buildSuggestions(BuildContext context) => const SizedBox(); }
内容的提问来源于stack exchange,提问作者Mahmoud Ali
相关产品推荐
相关产品推荐

