Commit 3c6d4f66 authored by Adam Barth's avatar Adam Barth

Add a default MediaQuery value

Now MediaQuery.of always returns a non-null value. By default, you get the
values associated with the current ui.Window.

Fixes #2894
parent 03830d56
...@@ -82,7 +82,7 @@ class FlexibleSpaceDemoState extends State<FlexibleSpaceDemo> { ...@@ -82,7 +82,7 @@ class FlexibleSpaceDemoState extends State<FlexibleSpaceDemo> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final double statusBarHeight = (MediaQuery.of(context)?.padding ?? EdgeInsets.zero).top; final double statusBarHeight = MediaQuery.of(context).padding.top;
return new Theme( return new Theme(
data: new ThemeData( data: new ThemeData(
brightness: ThemeBrightness.light, brightness: ThemeBrightness.light,
......
...@@ -35,7 +35,7 @@ class TabsDemoState extends State<TabsDemo> { ...@@ -35,7 +35,7 @@ class TabsDemoState extends State<TabsDemo> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final double statusBarHeight = (MediaQuery.of(context)?.padding ?? EdgeInsets.zero).top; final double statusBarHeight = MediaQuery.of(context).padding.top;
return new TabBarSelection<_Page>( return new TabBarSelection<_Page>(
values: _pages, values: _pages,
onChanged: (_Page value) { onChanged: (_Page value) {
......
...@@ -25,7 +25,7 @@ class GallerySection extends StatelessWidget { ...@@ -25,7 +25,7 @@ class GallerySection extends StatelessWidget {
} }
void showDemos(BuildContext context) { void showDemos(BuildContext context) {
final double statusBarHeight = (MediaQuery.of(context)?.padding ?? EdgeInsets.zero).top; final double statusBarHeight = MediaQuery.of(context).padding.top;
final ThemeData theme = new ThemeData( final ThemeData theme = new ThemeData(
brightness: Theme.of(context).brightness, brightness: Theme.of(context).brightness,
primarySwatch: colors primarySwatch: colors
......
...@@ -110,7 +110,7 @@ class AppBar extends StatelessWidget { ...@@ -110,7 +110,7 @@ class AppBar extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final double statusBarHeight = (MediaQuery.of(context)?.padding ?? EdgeInsets.zero).top; final double statusBarHeight = MediaQuery.of(context).padding.top;
final ThemeData theme = Theme.of(context); final ThemeData theme = Theme.of(context);
IconThemeData iconTheme = theme.primaryIconTheme; IconThemeData iconTheme = theme.primaryIconTheme;
......
...@@ -20,7 +20,7 @@ class DrawerHeader extends StatelessWidget { ...@@ -20,7 +20,7 @@ class DrawerHeader extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
assert(debugCheckHasMaterial(context)); assert(debugCheckHasMaterial(context));
final double statusBarHeight = (MediaQuery.of(context)?.padding ?? EdgeInsets.zero).top; final double statusBarHeight = MediaQuery.of(context).padding.top;
return new Container( return new Container(
height: statusBarHeight + kMaterialDrawerHeight, height: statusBarHeight + kMaterialDrawerHeight,
decoration: new BoxDecoration( decoration: new BoxDecoration(
......
...@@ -25,7 +25,7 @@ class _FlexibleSpaceBarState extends State<FlexibleSpaceBar> { ...@@ -25,7 +25,7 @@ class _FlexibleSpaceBarState extends State<FlexibleSpaceBar> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
assert(debugCheckHasScaffold(context)); assert(debugCheckHasScaffold(context));
final double statusBarHeight = (MediaQuery.of(context)?.padding ?? EdgeInsets.zero).top; final double statusBarHeight = MediaQuery.of(context).padding.top;
final Animation<double> animation = Scaffold.of(context).appBarAnimation; final Animation<double> animation = Scaffold.of(context).appBarAnimation;
final double appBarHeight = Scaffold.of(context).appBarHeight + statusBarHeight; final double appBarHeight = Scaffold.of(context).appBarHeight + statusBarHeight;
final double toolBarHeight = kToolBarHeight + statusBarHeight; final double toolBarHeight = kToolBarHeight + statusBarHeight;
......
...@@ -453,7 +453,7 @@ class ScaffoldState extends State<Scaffold> { ...@@ -453,7 +453,7 @@ class ScaffoldState extends State<Scaffold> {
} }
Widget _buildScrollableAppBar(BuildContext context) { Widget _buildScrollableAppBar(BuildContext context) {
final EdgeInsets padding = MediaQuery.of(context)?.padding ?? EdgeInsets.zero; final EdgeInsets padding = MediaQuery.of(context).padding;
final double expandedHeight = (config.appBar?.expandedHeight ?? 0.0) + padding.top; final double expandedHeight = (config.appBar?.expandedHeight ?? 0.0) + padding.top;
final double collapsedHeight = (config.appBar?.collapsedHeight ?? 0.0) + padding.top; final double collapsedHeight = (config.appBar?.collapsedHeight ?? 0.0) + padding.top;
final double minimumHeight = (config.appBar?.minimumHeight ?? 0.0) + padding.top; final double minimumHeight = (config.appBar?.minimumHeight ?? 0.0) + padding.top;
...@@ -500,7 +500,7 @@ class ScaffoldState extends State<Scaffold> { ...@@ -500,7 +500,7 @@ class ScaffoldState extends State<Scaffold> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final EdgeInsets padding = MediaQuery.of(context)?.padding ?? EdgeInsets.zero; final EdgeInsets padding = MediaQuery.of(context).padding;
if (_snackBars.length > 0) { if (_snackBars.length > 0) {
final ModalRoute<dynamic> route = ModalRoute.of(context); final ModalRoute<dynamic> route = ModalRoute.of(context);
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
import 'dart:ui' as ui show lerpDouble; import 'dart:ui' as ui show lerpDouble, WindowPadding;
import 'basic_types.dart'; import 'basic_types.dart';
...@@ -23,20 +23,26 @@ class EdgeInsets { ...@@ -23,20 +23,26 @@ class EdgeInsets {
/// Constructs insets where all the offsets are value. /// Constructs insets where all the offsets are value.
const EdgeInsets.all(double value) const EdgeInsets.all(double value)
: top = value, right = value, bottom = value, left = value; : left = value, top = value, right = value, bottom = value;
/// Constructs insets with only the given values non-zero. /// Constructs insets with only the given values non-zero.
const EdgeInsets.only({ const EdgeInsets.only({
this.left: 0.0,
this.top: 0.0, this.top: 0.0,
this.right: 0.0, this.right: 0.0,
this.bottom: 0.0, this.bottom: 0.0
this.left: 0.0
}); });
/// Constructs insets with symmetrical vertical and horizontal offsets. /// Constructs insets with symmetrical vertical and horizontal offsets.
const EdgeInsets.symmetric({ double vertical: 0.0, const EdgeInsets.symmetric({ double vertical: 0.0,
double horizontal: 0.0 }) double horizontal: 0.0 })
: top = vertical, left = horizontal, bottom = vertical, right = horizontal; : left = horizontal, top = vertical, right = horizontal, bottom = vertical;
EdgeInsets.fromWindowPadding(ui.WindowPadding padding)
: left = padding.left, top = padding.top, right = padding.right, bottom = padding.bottom;
/// The offset from the left.
final double left;
/// The offset from the top. /// The offset from the top.
final double top; final double top;
...@@ -47,11 +53,8 @@ class EdgeInsets { ...@@ -47,11 +53,8 @@ class EdgeInsets {
/// The offset from the bottom. /// The offset from the bottom.
final double bottom; final double bottom;
/// The offset from the left.
final double left;
/// Whether every dimension is non-negative. /// Whether every dimension is non-negative.
bool get isNonNegative => top >= 0.0 && right >= 0.0 && bottom >= 0.0 && left >= 0.0; bool get isNonNegative => left >= 0.0 && top >= 0.0 && right >= 0.0 && bottom >= 0.0;
/// The total offset in the vertical direction. /// The total offset in the vertical direction.
double get horizontal => left + right; double get horizontal => left + right;
...@@ -151,15 +154,15 @@ class EdgeInsets { ...@@ -151,15 +154,15 @@ class EdgeInsets {
if (other is! EdgeInsets) if (other is! EdgeInsets)
return false; return false;
final EdgeInsets typedOther = other; final EdgeInsets typedOther = other;
return top == typedOther.top && return left == typedOther.left &&
top == typedOther.top &&
right == typedOther.right && right == typedOther.right &&
bottom == typedOther.bottom && bottom == typedOther.bottom;
left == typedOther.left;
} }
@override @override
int get hashCode => hashValues(top, left, bottom, right); int get hashCode => hashValues(left, top, right, bottom);
@override @override
String toString() => "EdgeInsets($top, $right, $bottom, $left)"; String toString() => "EdgeInsets($left, $top, $right, $bottom)";
} }
...@@ -104,10 +104,6 @@ class WidgetsApp extends StatefulWidget { ...@@ -104,10 +104,6 @@ class WidgetsApp extends StatefulWidget {
WidgetsAppState<WidgetsApp> createState() => new WidgetsAppState<WidgetsApp>(); WidgetsAppState<WidgetsApp> createState() => new WidgetsAppState<WidgetsApp>();
} }
EdgeInsets _getPadding(ui.WindowPadding padding) {
return new EdgeInsets.fromLTRB(padding.left, padding.top, padding.right, padding.bottom);
}
class WidgetsAppState<T extends WidgetsApp> extends State<T> implements BindingObserver { class WidgetsAppState<T extends WidgetsApp> extends State<T> implements BindingObserver {
GlobalObjectKey _navigator; GlobalObjectKey _navigator;
...@@ -173,11 +169,7 @@ class WidgetsAppState<T extends WidgetsApp> extends State<T> implements BindingO ...@@ -173,11 +169,7 @@ class WidgetsAppState<T extends WidgetsApp> extends State<T> implements BindingO
} }
Widget result = new MediaQuery( Widget result = new MediaQuery(
data: new MediaQueryData( data: new MediaQueryData.fromWindow(ui.window),
size: ui.window.size,
devicePixelRatio: ui.window.devicePixelRatio,
padding: _getPadding(ui.window.padding)
),
child: new LocaleQuery( child: new LocaleQuery(
data: _localeData, data: _localeData,
child: new AssetVendor( child: new AssetVendor(
......
...@@ -4,7 +4,6 @@ ...@@ -4,7 +4,6 @@
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import 'debug.dart';
import 'framework.dart'; import 'framework.dart';
import 'media_query.dart'; import 'media_query.dart';
...@@ -17,7 +16,6 @@ class ChildView extends StatelessWidget { ...@@ -17,7 +16,6 @@ class ChildView extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
assert(debugCheckHasMediaQuery(context));
return new _ChildViewWidget( return new _ChildViewWidget(
child: child, child: child,
scale: MediaQuery.of(context).devicePixelRatio scale: MediaQuery.of(context).devicePixelRatio
......
...@@ -5,25 +5,6 @@ ...@@ -5,25 +5,6 @@
import 'dart:collection'; import 'dart:collection';
import 'framework.dart'; import 'framework.dart';
import 'media_query.dart';
bool debugCheckHasMediaQuery(BuildContext context) {
assert(() {
if (MediaQuery.of(context) == null) {
Element element = context;
throw new FlutterError(
'No MediaQuery widget found.\n'
'${element.widget.runtimeType} widgets require a MediaQuery widget ancestor.\n'
'The specific widget that could not find a MediaQuery ancestor was:\n'
' ${element.widget}'
'The ownership chain for the affected widget is:\n'
' ${element.debugGetOwnershipChain(10)}'
);
}
return true;
});
return true;
}
Key _firstNonUniqueKey(Iterable<Widget> widgets) { Key _firstNonUniqueKey(Iterable<Widget> widgets) {
Set<Key> keySet = new HashSet<Key>(); Set<Key> keySet = new HashSet<Key>();
......
...@@ -300,14 +300,12 @@ class _FocusState extends State<Focus> { ...@@ -300,14 +300,12 @@ class _FocusState extends State<Focus> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
MediaQueryData data = MediaQuery.of(context); MediaQueryData data = MediaQuery.of(context);
if (data != null) { Size newMediaSize = data.size;
Size newMediaSize = data.size; EdgeInsets newMediaPadding = data.padding;
EdgeInsets newMediaPadding = data.padding; if (newMediaSize != _mediaSize || newMediaPadding != _mediaPadding) {
if (newMediaSize != _mediaSize || newMediaPadding != _mediaPadding) { _mediaSize = newMediaSize;
_mediaSize = newMediaSize; _mediaPadding = newMediaPadding;
_mediaPadding = newMediaPadding; scheduleMicrotask(_ensureVisibleIfFocused);
scheduleMicrotask(_ensureVisibleIfFocused);
}
} }
return new Semantics( return new Semantics(
container: true, container: true,
......
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
import 'dart:ui' as ui;
import 'basic.dart'; import 'basic.dart';
import 'framework.dart'; import 'framework.dart';
...@@ -18,6 +20,11 @@ enum Orientation { ...@@ -18,6 +20,11 @@ enum Orientation {
class MediaQueryData { class MediaQueryData {
const MediaQueryData({ this.size, this.devicePixelRatio, this.padding }); const MediaQueryData({ this.size, this.devicePixelRatio, this.padding });
MediaQueryData.fromWindow(ui.Window window)
: size = window.size,
devicePixelRatio = window.devicePixelRatio,
padding = new EdgeInsets.fromWindowPadding(window.padding);
/// The size of the media (e.g, the size of the screen). /// The size of the media (e.g, the size of the screen).
final Size size; final Size size;
...@@ -76,7 +83,7 @@ class MediaQuery extends InheritedWidget { ...@@ -76,7 +83,7 @@ class MediaQuery extends InheritedWidget {
/// keeping your widget up-to-date. /// keeping your widget up-to-date.
static MediaQueryData of(BuildContext context) { static MediaQueryData of(BuildContext context) {
MediaQuery query = context.inheritFromWidgetOfExactType(MediaQuery); MediaQuery query = context.inheritFromWidgetOfExactType(MediaQuery);
return query == null ? null : query.data; return query?.data ?? new MediaQueryData.fromWindow(ui.window);
} }
@override @override
......
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:ui' as ui;
import 'package:flutter_test/flutter_test.dart';
import 'package:flutter/widgets.dart';
import 'package:test/test.dart';
void main() {
test('MediaQuery has a default', () {
testWidgets((WidgetTester tester) {
Size size;
tester.pumpWidget(
new Builder(
builder: (BuildContext context) {
size = MediaQuery.of(context).size;
return new Container();
}
)
);
expect(size, equals(ui.window.size));
});
});
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment