Flutter初学者遇红屏错误:未找到Media Query Widget祖先
Flutter侧边导航布局报错:No MediaQuery widget ancestor found
我是Flutter初学者,尝试用side_navigation包创建带侧边菜单的简单应用布局,参考官方入门示例写了如下代码,但运行后出现红屏,提示**"no media query widget ancestor found...."**,尝试更换返回类型也没解决,请求帮助。
import 'package:flutter/material.dart'; import 'package:flutter/foundation.dart'; import 'package:side_navigation/side_navigation.dart'; void main() { runApp(const MainView()); } class MainView extends StatefulWidget { const MainView({Key? key}) : super(key: key); @override _MainViewState createState() => _MainViewState(); } class _MainViewState extends State<MainView> { List<Widget> views = const [ Center( child: Text('Dashboard'), ), Center( child: Text('Account'), ), Center( child: Text('Settings'), ), ]; int selectedIndex = 0; @override Widget build(BuildContext context) { return Scaffold( body: Row( children: [ SideNavigationBar( selectedIndex: selectedIndex, items: const [ SideNavigationBarItem( icon: Icons.dashboard, label: 'Dashboard', ), SideNavigationBarItem( icon: Icons.person, label: 'Account', ), SideNavigationBarItem( icon: Icons.settings, label: 'Settings', ), ], onTap: (index) { setState(() { selectedIndex = index; }); }, theme: SideNavigationBarTheme( backgroundColor: Colors.grey, togglerTheme: SideNavigationBarTogglerTheme.standard(), itemTheme: SideNavigationBarItemTheme.standard(), dividerTheme: SideNavigationBarDividerTheme.standard(), ), ), Expanded( child: views.elementAt(selectedIndex), ) ], ), ); } }
问题原因与修复方案
这个错误的核心是应用根组件缺少MaterialApp包裹。SideNavigationBar等组件需要依赖MediaQuery获取屏幕尺寸信息,而MediaQuery是由MaterialApp(或CupertinoApp)提供的,直接把MainView作为runApp的参数会导致组件找不到所需的MediaQuery上下文。
只需修改main函数,将MainView放入MaterialApp中即可解决:
import 'package:flutter/material.dart'; import 'package:flutter/foundation.dart'; import 'package:side_navigation/side_navigation.dart'; void main() { // 用MaterialApp包裹MainView runApp(const MaterialApp( home: MainView(), debugShowCheckedModeBanner: false, // 可选:关闭右上角调试标签 )); } class MainView extends StatefulWidget { const MainView({Key? key}) : super(key: key); @override _MainViewState createState() => _MainViewState(); } class _MainViewState extends State<MainView> { List<Widget> views = const [ Center( child: Text('Dashboard'), ), Center( child: Text('Account'), ), Center( child: Text('Settings'), ), ]; int selectedIndex = 0; @override Widget build(BuildContext context) { return Scaffold( body: Row( children: [ SideNavigationBar( selectedIndex: selectedIndex, items: const [ SideNavigationBarItem( icon: Icons.dashboard, label: 'Dashboard', ), SideNavigationBarItem( icon: Icons.person, label: 'Account', ), SideNavigationBarItem( icon: Icons.settings, label: 'Settings', ), ], onTap: (index) { setState(() { selectedIndex = index; }); }, theme: SideNavigationBarTheme( backgroundColor: Colors.grey, togglerTheme: SideNavigationBarTogglerTheme.standard(), itemTheme: SideNavigationBarItemTheme.standard(), dividerTheme: SideNavigationBarDividerTheme.standard(), ), ), Expanded( child: views.elementAt(selectedIndex), ) ], ), ); } }
补充说明
MaterialApp是Material风格Flutter应用的标准根组件,它会自动提供MediaQuery、主题、路由等核心服务,几乎所有Material组件都依赖它提供的上下文。- 如果是iOS风格应用,可以用
CupertinoApp替代MaterialApp,同样能解决这个问题。
内容的提问来源于stack exchange,提问作者Glocha
相关产品推荐
相关产品推荐

