断言失败:MediaQuery.of() 使用的上下文不包含 MediaQuery 祖先。
Assertion failed: MediaQuery.of() called with a context that does not contain a MediaQuery ancestor.
ID: flutter/assertion-error-media-query-before-run
版本兼容性
| 版本 | 状态 | 引入 | 弃用 | 备注 |
|---|---|---|---|---|
| flutter 3.10 | active | — | — | — |
| flutter 3.22 | active | — | — | — |
| dart 3.0 | active | — | — | — |
根因分析
MediaQuery.of(context) 在 widget 被插入到具有 MaterialApp 或 WidgetsApp 祖先(提供 MediaQuery)的 widget 树之前被调用,通常在 build 期间但在 runApp() 之前,或在一个不是 MaterialApp 后代的 widget 中。
English
MediaQuery.of(context) is called before the widget is inserted into the widget tree that has a MaterialApp or WidgetsApp ancestor providing MediaQuery, typically during build before runApp() or in a widget that is not a descendant of MaterialApp.
官方文档
https://api.flutter.dev/flutter/widgets/MediaQuery/of.html解决方案
-
确保 MediaQuery.of(context) 仅在 MaterialApp 或 WidgetsApp 后代的 build 方法中调用。如果在 initState 中需要,使用 WidgetsBinding.instance.addPostFrameCallback 延迟调用。
-
将 MediaQuery 数据作为参数传递给需要它的 widget,而不是在其中调用 MediaQuery.of(context)。
无效尝试
常见但无效的做法:
-
Adding MediaQuery.of(context) directly in main() before runApp()
100% 失败
The context from runApp() is not available; MediaQuery is only set up after the MaterialApp widget is built.
-
Using a global variable to store MediaQuery data before the widget tree is built
90% 失败
MediaQuery depends on the widget tree context; it cannot be accessed outside the build method or before the tree is established.