Flutter如何为MediaQuery设置MaterialApp祖先解决无祖先报错
错误原因
MediaQuery是 Flutter 内置的用于获取屏幕、窗口尺寸相关信息的组件,它的实例由MaterialApp或WidgetsApp这类根布局组件自动创建,必须在上述组件的子树中调用MediaQuery.of(context)才能正常获取到实例。你当前的代码在还未返回MaterialApp时就调用了MediaQuery.of(context),传入的context没有对应的MediaQuery祖先节点,因此会抛出该报错。
修复代码
你只需要将布局判断逻辑放到 MaterialApp 的子树中即可,完整修复后的代码如下:
import 'package:flutter/material.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({Key? key}) : super(key: key); @override Widget build(BuildContext context) { // 先返回MaterialApp作为根组件,完成MediaQuery的初始化 return MaterialApp( // 通过Builder拿到子树的context,此时context已包含MediaQuery实例 home: Builder( builder: (context) { var screenSize = MediaQuery.of(context).size; if (screenSize.width < 600) { return lay1(); } else if (screenSize.width < 800) { return lay2(); } else { return lay3(); } }, ), ); } } Widget lay1() { return Container( color: Colors.lightGreenAccent, ); } Widget lay2() { return Container( color: Colors.lightBlueAccent, ); } Widget lay3() { return Container( color: Colors.orangeAccent, ); }
补充说明
- 你也可以将home对应的布局逻辑抽成独立的Stateless/Stateful组件,不需要额外使用Builder,独立组件的build方法传入的context天然属于MaterialApp的子树,可以直接调用MediaQuery。
- 自适应布局场景更推荐使用
LayoutBuilder组件,它可以直接获取父组件的约束尺寸,不需要依赖MediaQuery,适配窗口动态缩放的场景更灵活。
内容的提问来源于stack exchange,提问作者lettuce
相关产品推荐
相关产品推荐

