已用MaterialApp仍遇FlutterError: No MediaQuery widget ancestor found,求排查
问题分析与解决方法
问题根源
你在MyApp的build方法中直接调用MediaQuery.of(context),但这里的context属于MyApp组件本身,此时MaterialApp还未完成构建——MediaQuery是由MaterialApp内部注入的,当前上下文无法获取到它的实例,因此触发No MediaQuery widget ancestor found错误。
移除MaterialApp后仍报错,是因为MediaQuery依赖MaterialApp、CupertinoApp或WidgetsApp提供,没有这些顶层组件时,整个组件树里都不存在MediaQuery,错误自然会持续。
解决方法
有两种简单的修复方式:
方式一:将页面内容抽为独立子组件
把需要使用MediaQuery的部分拆成单独的组件,这样组件的上下文会继承自MaterialApp,就能正常获取MediaQuery:
void main() async { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return MaterialApp( home: const HomePage(), ); } } class HomePage extends StatelessWidget { const HomePage({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return Scaffold( body: Container( decoration: BoxDecoration( image: DecorationImage( image: AssetImage('assets/images/my_bg.png'), fit: BoxFit.cover), ), child: Column( mainAxisAlignment: MainAxisAlignment.end, children: [ Container( padding: const EdgeInsets.all(16), width: MediaQuery.of(context).size.width, child: AuthGate(), ) ], ), ), ); } }
方式二:用Builder组件创建新上下文
通过Builder包裹需要使用MediaQuery的部分,Builder会生成一个继承自MaterialApp的新上下文:
void main() async { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( body: Container( decoration: BoxDecoration( image: DecorationImage( image: AssetImage('assets/images/my_bg.png'), fit: BoxFit.cover), ), child: Column( mainAxisAlignment: MainAxisAlignment.end, children: [ Builder( builder: (BuildContext innerContext) { return Container( padding: const EdgeInsets.all(16), width: MediaQuery.of(innerContext).size.width, child: AuthGate(), ); }, ) ], ), ), ), ); } }
内容的提问来源于stack exchange,提问作者user18124547
相关产品推荐
相关产品推荐

