Flutter搜索应用MediaQuery异常处理咨询:解决MediaQuery.of()调用上下文无MediaQuery的问题
解决Flutter红屏异常:MediaQuery.of()找不到MediaQuery祖先的问题
嘿,我来帮你搞定这个红屏问题!先拆解下错误根源,再给你具体的修复方案。
错误原因分析
你遇到的报错MediaQuery.of() called with a context that does not contain a MediaQuery,核心问题很明确:
Flutter的
MediaQuery是由MaterialApp(或WidgetsApp)这类顶层容器组件提供的,而你的MyFirstApp直接返回了Scaffold,没有把它包裹在MaterialApp内部。当showSearch或者Scaffold尝试获取MediaQuery时,找不到对应的祖先依赖,直接触发红屏报错。
具体修复步骤
只需要修改main.dart里的MyFirstApp类,把Scaffold放在MaterialApp的home属性中即可,同时顺便修复代码里的一个小语法错误(query = " ");多了个多余的闭合括号)。
修改后的完整main.dart代码
import 'package:flutter/material.dart'; void main() { runApp(MyFirstApp()); } class MyFirstApp extends StatelessWidget { @override Widget build(BuildContext context) { // 关键:用MaterialApp包裹Scaffold,提供MediaQuery等必要的上下文依赖 return MaterialApp( home: Scaffold( appBar: AppBar( title: Text("Search..."), actions: <Widget>[ IconButton( icon: Icon(Icons.search), onPressed: () { showSearch(context: context, delegate: DataSearch()); }) ], ), drawer: Drawer(), ), ); } } class DataSearch extends SearchDelegate<String> { final data1 = ["Amr", "Amir", "Moatasem", "Gamal", "Tasneem"]; final data2 = ["Amr", "Amir"]; @override List<Widget> buildActions(BuildContext context) { return <Widget>[ IconButton( icon: Icon(Icons.clear), onPressed: () { // 修复语法错误:移除多余的闭合括号 query = ""; }) ]; } @override Widget buildLeading(BuildContext context) { return IconButton( icon: AnimatedIcon( icon: AnimatedIcons.menu_arrow, progress: transitionAnimation, ), onPressed: () { close(context, null); }); } @override Widget buildResults(BuildContext context) { return Container( child: Center( child: Text(query), ), ); } @override Widget buildSuggestions(BuildContext context) { final suggestion = query.isEmpty ? data2 : data1.where((p) => p.startsWith(query)).toList(); return ListView.builder( itemBuilder: (context, index) => ListTile( onTap: () { showResults(context); }, leading: Icon(Icons.question_answer), title: RichText( text: TextSpan( text: suggestion[index].substring(0, query.length), style: TextStyle(color: Colors.black, fontStyle: FontStyle.italic), children: [ TextSpan( text: suggestion[index].substring(query.length), style: TextStyle(color: Colors.red)) ]), ), ), itemCount: suggestion.length, ); } }
额外提示:关于你的测试代码
你的Widget test.dart里的测试是针对计数器功能的,但主代码里并没有计数器组件,所以这个测试必然会失败。如果要测试搜索功能,可以改成类似这样的示例测试:
import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:testtest/main.dart'; void main() { testWidgets('Search button triggers search delegate', (WidgetTester tester) async { // 构建应用并触发渲染 await tester.pumpWidget(MyFirstApp()); // 验证搜索按钮存在 expect(find.byIcon(Icons.search), findsOneWidget); // 点击搜索按钮并触发渲染 await tester.tap(find.byIcon(Icons.search)); await tester.pump(); // 验证搜索界面已弹出 expect(find.byType(SearchBar), findsOneWidget); }); }
内容的提问来源于stack exchange,提问作者Youssef Amir
相关产品推荐
相关产品推荐

