[Flutter]解决No MediaQuery ancestor could be found starting from the context that was passed to MediaQuery的问题
使用video_player插件()时,为了更直观的看看插件的实现效果。于是将官方的Example启动后发现了如下异常:
======== Exception caught by widgets library =======================================================
The following assertion was thrown building Scaffold-[<'home_page'>](dirty, state: ScaffoldState#5861e(tickers: tracking 2 tickers)):
No MediaQuery widget ancestor found.
Scaffold widgets require a MediaQuery widget ancestor.
The specific widget that could not find a MediaQuery ancestor was: Scaffold-[<'home_page'>]
dirty
state: ScaffoldState#5861e(tickers: tracking 2 tickers)
The ownership chain for the affected widget is: "Scaffold-[<'home_page'>] ← _TabControllerScope ← DefaultTabController ← _App ← [root]"
No MediaQuery ancestor could be found starting from the context that was passed to MediaQuery.of(). This can happen because you have not added a WidgetsApp, CupertinoApp, or MaterialApp widget (those widgets introduce a MediaQuery), or it can happen if the context you use comes from a widget above those widgets.
The relevant error-causing widget was:
Scaffold-[<'home_page'>] Scaffold:file:///F:/Git/blog/lib/main.dart:17:16
When the exception was thrown, this was the stack:
#0 debugCheckHasMediaQuery.<anonymous closure> (package:flutter/src/widgets/debug.dart:297:7)
#1 debugCheckHasMediaQuery (package:flutter/src/widgets/debug.dart:312:4)
#2 ScaffoldState.build (package:flutter/src/material/scaffold.dart:2762:12)
#3 StatefulElement.build (package:flutter/src/widgets/framework.dart:5080:27)
#4 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4968:15)
#5 StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:5133:11)
#6 Element.rebuild (package:flutter/src/widgets/framework.dart:4690:5)
#7 ComponentElement._firstBuild (package:flutter/src/widgets/framework.dart:4950:5)
#8 StatefulElement._firstBuild (package:flutter/src/widgets/framework.dart:5124:11)
#9 ComponentElement.mount (package:flutter/src/widgets/framework.dart:4944:5)
... Normal element mounting (21 frames)
#30 Element.inflateWidget (package:flutter/src/widgets/framework.dart:3953:16)
#31 Element.updateChild (package:flutter/src/widgets/framework.dart:3682:18)
#32 RenderObjectToWidgetElement._rebuild (package:flutter/src/widgets/binding.dart:1176:16)
#33 RenderObjectToWidgetElement.mount (package:flutter/src/widgets/binding.dart:1145:5)
#34 RenderObjectToWidgetAdapter.attachToRenderTree.<anonymous closure> (package:flutter/src/widgets/binding.dart:1092:18)
#35 BuildOwner.buildScope (package:flutter/src/widgets/framework.dart:2682:19)
#36 RenderObjectToWidgetAdapter.attachToRenderTree (package:flutter/src/widgets/binding.dart:1091:13)
#37 WidgetsBinding.attachRootWidget (package:flutter/src/widgets/binding.dart:926:7)
#38 WidgetsBinding.scheduleAttachRootWidget.<anonymous closure> (package:flutter/src/widgets/binding.dart:906:7)
#42 _RawReceivePort._handleMessage (dart:isolate-patch/isolate_patch.dart:192:26)
(elided 3 frames from class _Timer and dart:async-patch)
====================================================================================================
W/Parcel (17640): Expecting binder but got null!
在上面的异常信息中,抛出了一个关键的一句话:
This can happen because you have not added a WidgetsApp, CupertinoApp, or MaterialApp widget (those widgets introduce a MediaQuery), or it can happen if the context you use comes from a widget above those widgets.
因为我这里是用Scaffold包裹组件的,代码如下:
import 'package:flutter/material.dart';
import 'package:video_player/video_player.dart';
void main() {
runApp(_App());
}
class _App extends StatelessWidget {
@override
Widget build(BuildContext context) {
return DefaultTabController(
length: 3,
child: Scaffold(
key: const ValueKey<String>('home_page'),
appBar: AppBar(
title: const Text('Video player example'),
actions: <Widget>[
IconButton(
key: const ValueKey<String>('push_tab'),
icon: const Icon(Icons.navigation),
onPressed: () {
Navigator.push<_PlayerVideoAndPopPage>(
context,
MaterialPageRoute<_PlayerVideoAndPopPage>(
builder: (BuildContext context) => _PlayerVideoAndPopPage(),
),
);
},
)
],
bottom: const TabBar(
isScrollable: true,
tabs: <Widget>[
Tab(
icon: Icon(Icons.cloud),
text: 'Remote',
),
Tab(icon: Icon(Icons.insert_drive_file), text: 'Asset'),
Tab(icon: Icon(Icons.list), text: 'List example'),
],
),
),
body: TabBarView(
children: <Widget>[
_BumbleBeeRemoteVideo(),
_ButterFlyAssetVideo(),
_ButterFlyAssetVideoInList(),
],
),
),
);
}
}
///以下代码省略 详见https://pub.dev/packages/video_player/versions/2.1.4/example
...
以上异常信息说明,这个Scaffold必须使用MaterialApp进行包裹才行,所以修改代码:
import 'package:flutter/material.dart';
import 'package:video_player/video_player.dart';
void main() {
runApp(_App());
}
class _App extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: DefaultTabController(
length: 3,
child: Scaffold(
key: const ValueKey<String>('home_page'),
appBar: AppBar(
title: const Text('Video player example'),
actions: <Widget>[
IconButton(
key: const ValueKey<String>('push_tab'),
icon: const Icon(Icons.navigation),
onPressed: () {
Navigator.push<_PlayerVideoAndPopPage>(
context,
MaterialPageRoute<_PlayerVideoAndPopPage>(
builder: (BuildContext context) => _PlayerVideoAndPopPage(),
),
);
},
)
],
bottom: const TabBar(
isScrollable: true,
tabs: <Widget>[
Tab(
icon: Icon(Icons.cloud),
text: 'Remote',
),
Tab(icon: Icon(Icons.insert_drive_file), text: 'Asset'),
Tab(icon: Icon(Icons.list), text: 'List example'),
],
),
),
body: TabBarView(
children: <Widget>[
_BumbleBeeRemoteVideo(),
_ButterFlyAssetVideo(),
_ButterFlyAssetVideoInList(),
],
),
),
),
);
}
}
///以下代码省略 详见https://pub.dev/packages/video_player/versions/2.1.4/example
...
修改完成,启动后正常。