Unverified Commit 991da4f7 authored by Kate Lovett's avatar Kate Lovett Committed by GitHub

Updating MediaQuery with viewPadding (#33999)

* Updating MediaQuery with viewPadding

* Added tests

* Fixed test

* Updating remove logic & tests

* Diagram and documentation

* Review feedback
parent ce4f15cd
...@@ -2,6 +2,7 @@ ...@@ -2,6 +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:math' as math;
import 'dart:ui' as ui; import 'dart:ui' as ui;
import 'dart:ui' show Brightness; import 'dart:ui' show Brightness;
...@@ -32,24 +33,52 @@ enum Orientation { ...@@ -32,24 +33,52 @@ enum Orientation {
/// exception, unless the `nullOk` argument is set to true, in which case it /// exception, unless the `nullOk` argument is set to true, in which case it
/// returns null. /// returns null.
/// ///
/// MediaQueryData includes two [EdgeInsets] values: /// ## Insets and Padding
/// [padding] and [viewInsets]. These
/// values reflect the configuration of the device and are used by
/// many top level widgets, like [SafeArea] and the Cupertino and
/// Material scaffold widgets. The padding value defines areas that
/// might not be completely visible, like the display "notch" on the
/// iPhone X. The viewInsets value defines areas that aren't visible at
/// all, typically because they're obscured by the device's keyboard.
/// ///
/// The viewInsets and padding values are independent, they're both /// ![A diagram of padding, viewInsets, and viewPadding in correlation with each
/// measured from the edges of the MediaQuery widget's bounds. The /// other](https://flutter.github.io/assets-for-api-docs/assets/widgets/media_query.png)
/// bounds of the top level MediaQuery created by [WidgetsApp] are the
/// same as the window that contains the app.
/// ///
/// Widgets whose layouts consume space defined by [viewInsets] or /// This diagram illustrates how [padding] relates to [viewPadding] and
/// [padding] should enclose their children in secondary MediaQuery /// [viewInsets], shown here in its simplest configuration, as the difference
/// between the two. In cases when the viewInsets exceed the viewPadding, like
/// when a software keyboard is shown below, padding goes to zero rather than a
/// negative value. Therefore, padding is calculated by taking
/// `max(0.0, viewPadding - viewInsets)`.
///
/// {@animation 300 300 https://flutter.github.io/assets-for-api-docs/assets/widgets/window_padding.mp4}
///
/// In this diagram, the black areas represent system UI that the app cannot
/// draw over. The red area represents view padding that the application may not
/// be able to detect gestures in and may not want to draw in. The grey area
/// represents the system keyboard, which can cover over the bottom view padding
/// when visible.
///
/// MediaQueryData includes three [EdgeInsets] values:
/// [padding], [viewPadding], and [viewInsets]. These values reflect the
/// configuration of the device and are used and optionally consumed by widgets
/// that position content within these insets. The padding value defines areas
/// that might not be completely visible, like the display "notch" on the iPhone
/// X. The viewInsets value defines areas that aren't visible at all, typically
/// because they're obscured by the device's keyboard. Similar to viewInsets,
/// viewPadding does not differentiate padding in areas that may be obscured.
/// For example, by using the viewPadding property, padding would defer to the
/// iPhone "safe area" regardless of whether a keyboard is showing.
///
/// The viewInsets and viewPadding are independent values, they're
/// measured from the edges of the MediaQuery widget's bounds. Together they
/// inform the [padding] property. The bounds of the top level MediaQuery
/// created by [WidgetsApp] are the same as the window that contains the app.
///
/// Widgets whose layouts consume space defined by [viewInsets], [viewPadding],
/// or [padding] should enclose their children in secondary MediaQuery
/// widgets that reduce those properties by the same amount. /// widgets that reduce those properties by the same amount.
/// The [removePadding] and [removeInsets] methods are useful for this. /// The [removePadding], [removeViewPadding], and [removeInsets] methods are
/// useful for this.
/// See also:
///
/// * [Scaffold], [SafeArea], [CupertinoTabScaffold], and
/// [CupertinoPageScaffold], all of which are informed by [padding],
/// [viewPadding], and [viewInsets].
@immutable @immutable
class MediaQueryData { class MediaQueryData {
/// Creates data for a media query with explicit values. /// Creates data for a media query with explicit values.
...@@ -63,6 +92,7 @@ class MediaQueryData { ...@@ -63,6 +92,7 @@ class MediaQueryData {
this.platformBrightness = Brightness.light, this.platformBrightness = Brightness.light,
this.padding = EdgeInsets.zero, this.padding = EdgeInsets.zero,
this.viewInsets = EdgeInsets.zero, this.viewInsets = EdgeInsets.zero,
this.viewPadding = EdgeInsets.zero,
this.alwaysUse24HourFormat = false, this.alwaysUse24HourFormat = false,
this.accessibleNavigation = false, this.accessibleNavigation = false,
this.invertColors = false, this.invertColors = false,
...@@ -82,6 +112,7 @@ class MediaQueryData { ...@@ -82,6 +112,7 @@ class MediaQueryData {
textScaleFactor = window.textScaleFactor, textScaleFactor = window.textScaleFactor,
platformBrightness = window.platformBrightness, platformBrightness = window.platformBrightness,
padding = EdgeInsets.fromWindowPadding(window.padding, window.devicePixelRatio), padding = EdgeInsets.fromWindowPadding(window.padding, window.devicePixelRatio),
viewPadding = EdgeInsets.fromWindowPadding(window.viewPadding, window.devicePixelRatio),
viewInsets = EdgeInsets.fromWindowPadding(window.viewInsets, window.devicePixelRatio), viewInsets = EdgeInsets.fromWindowPadding(window.viewInsets, window.devicePixelRatio),
accessibleNavigation = window.accessibilityFeatures.accessibleNavigation, accessibleNavigation = window.accessibilityFeatures.accessibleNavigation,
invertColors = window.accessibilityFeatures.invertColors, invertColors = window.accessibilityFeatures.invertColors,
...@@ -128,15 +159,16 @@ class MediaQueryData { ...@@ -128,15 +159,16 @@ class MediaQueryData {
/// When a mobile device's keyboard is visible `viewInsets.bottom` /// When a mobile device's keyboard is visible `viewInsets.bottom`
/// corresponds to the top of the keyboard. /// corresponds to the top of the keyboard.
/// ///
/// This value is independent of the [padding]: both values are /// This value is independent of the [padding] and [viewPadding]. viewPadding
/// measured from the edges of the [MediaQuery] widget's bounds. The /// is measured from the edges of the [MediaQuery] widget's bounds. Padding is
/// bounds of the top level MediaQuery created by [WidgetsApp] are the /// calculated based on the viewPadding and viewInsets. The bounds of the top
/// same as the window (often the mobile device screen) that contains the app. /// level MediaQuery created by [WidgetsApp] are the same as the window
/// (often the mobile device screen) that contains the app.
/// ///
/// See also: /// See also:
/// ///
/// * [MediaQueryData], which provides some additional detail about this /// * [ui.window], which provides some additional detail about this property
/// property and how it differs from [padding]. /// and how it relates to [padding] and [viewPadding].
final EdgeInsets viewInsets; final EdgeInsets viewInsets;
/// The parts of the display that are partially obscured by system UI, /// The parts of the display that are partially obscured by system UI,
...@@ -148,14 +180,36 @@ class MediaQueryData { ...@@ -148,14 +180,36 @@ class MediaQueryData {
/// for subsequent descendants in the widget tree by inserting a new /// for subsequent descendants in the widget tree by inserting a new
/// [MediaQuery] widget using the [MediaQuery.removePadding] factory. /// [MediaQuery] widget using the [MediaQuery.removePadding] factory.
/// ///
/// Padding is derived from the values of viewInsets and viewPadding.
///
/// See also: /// See also:
/// ///
/// * [MediaQueryData], which provides some additional detail about this /// * [ui.window], which provides some additional detail about this
/// property and how it differs from [viewInsets]. /// property and how it relates to [viewInsets] and [viewPadding].
/// * [SafeArea], a widget that consumes this padding with a [Padding] widget /// * [SafeArea], a widget that consumes this padding with a [Padding] widget
/// and automatically removes it from the [MediaQuery] for its child. /// and automatically removes it from the [MediaQuery] for its child.
final EdgeInsets padding; final EdgeInsets padding;
/// The parts of the display that are partially obscured by system UI,
/// typically by the hardware display "notches" or the system status bar.
///
/// This value remains the same regardless of whether the system is reporting
/// other obstructions in the same physical area of the screen. For example, a
/// software keyboard on the bottom of the screen that may cover and consume
/// the same area that requires bottom padding will not affect this value.
///
/// This value is independent of the [padding] and [viewInsets]: their values
/// are measured from the edges of the [MediaQuery] widget's bounds. The
/// bounds of the top level MediaQuery created by [WidgetsApp] are the
/// same as the window that contains the app. On mobile devices, this will
/// typically be the full screen.
///
/// See also:
///
/// * [ui.window], which provides some additional detail about this
/// property and how it relates to [padding] and [viewInsets].
final EdgeInsets viewPadding;
/// Whether to use 24-hour format when formatting time. /// Whether to use 24-hour format when formatting time.
/// ///
/// The behavior of this flag is different across platforms: /// The behavior of this flag is different across platforms:
...@@ -218,6 +272,7 @@ class MediaQueryData { ...@@ -218,6 +272,7 @@ class MediaQueryData {
double textScaleFactor, double textScaleFactor,
Brightness platformBrightness, Brightness platformBrightness,
EdgeInsets padding, EdgeInsets padding,
EdgeInsets viewPadding,
EdgeInsets viewInsets, EdgeInsets viewInsets,
bool alwaysUse24HourFormat, bool alwaysUse24HourFormat,
bool disableAnimations, bool disableAnimations,
...@@ -231,6 +286,7 @@ class MediaQueryData { ...@@ -231,6 +286,7 @@ class MediaQueryData {
textScaleFactor: textScaleFactor ?? this.textScaleFactor, textScaleFactor: textScaleFactor ?? this.textScaleFactor,
platformBrightness: platformBrightness ?? this.platformBrightness, platformBrightness: platformBrightness ?? this.platformBrightness,
padding: padding ?? this.padding, padding: padding ?? this.padding,
viewPadding: viewPadding ?? this.viewPadding,
viewInsets: viewInsets ?? this.viewInsets, viewInsets: viewInsets ?? this.viewInsets,
alwaysUse24HourFormat: alwaysUse24HourFormat ?? this.alwaysUse24HourFormat, alwaysUse24HourFormat: alwaysUse24HourFormat ?? this.alwaysUse24HourFormat,
invertColors: invertColors ?? this.invertColors, invertColors: invertColors ?? this.invertColors,
...@@ -254,6 +310,7 @@ class MediaQueryData { ...@@ -254,6 +310,7 @@ class MediaQueryData {
/// * [SafeArea], which both removes the padding from the [MediaQuery] and /// * [SafeArea], which both removes the padding from the [MediaQuery] and
/// adds a [Padding] widget. /// adds a [Padding] widget.
/// * [removeViewInsets], the same thing but for [viewInsets]. /// * [removeViewInsets], the same thing but for [viewInsets].
/// * [removeViewPadding], the same thing but for [viewPadding].
MediaQueryData removePadding({ MediaQueryData removePadding({
bool removeLeft = false, bool removeLeft = false,
bool removeTop = false, bool removeTop = false,
...@@ -273,6 +330,12 @@ class MediaQueryData { ...@@ -273,6 +330,12 @@ class MediaQueryData {
right: removeRight ? 0.0 : null, right: removeRight ? 0.0 : null,
bottom: removeBottom ? 0.0 : null, bottom: removeBottom ? 0.0 : null,
), ),
viewPadding: viewPadding.copyWith(
left: math.max(0.0, viewPadding.left - padding.left),
top: math.max(0.0, viewPadding.top - padding.top),
right: math.max(0.0, viewPadding.right - padding.right),
bottom: math.max(0.0, viewPadding.bottom - padding.bottom),
),
viewInsets: viewInsets, viewInsets: viewInsets,
alwaysUse24HourFormat: alwaysUse24HourFormat, alwaysUse24HourFormat: alwaysUse24HourFormat,
disableAnimations: disableAnimations, disableAnimations: disableAnimations,
...@@ -294,6 +357,7 @@ class MediaQueryData { ...@@ -294,6 +357,7 @@ class MediaQueryData {
/// * [new MediaQuery.removeViewInsets], which uses this method to remove /// * [new MediaQuery.removeViewInsets], which uses this method to remove
/// padding from the ambient [MediaQuery]. /// padding from the ambient [MediaQuery].
/// * [removePadding], the same thing but for [padding]. /// * [removePadding], the same thing but for [padding].
/// * [removeViewPadding], the same thing but for [viewPadding].
MediaQueryData removeViewInsets({ MediaQueryData removeViewInsets({
bool removeLeft = false, bool removeLeft = false,
bool removeTop = false, bool removeTop = false,
...@@ -308,6 +372,12 @@ class MediaQueryData { ...@@ -308,6 +372,12 @@ class MediaQueryData {
textScaleFactor: textScaleFactor, textScaleFactor: textScaleFactor,
platformBrightness: platformBrightness, platformBrightness: platformBrightness,
padding: padding, padding: padding,
viewPadding: viewPadding.copyWith(
left: math.max(0.0, viewPadding.left - viewInsets.left),
top: math.max(0.0, viewPadding.top - viewInsets.top),
right: math.max(0.0, viewPadding.right - viewInsets.right),
bottom: math.max(0.0, viewPadding.bottom - viewInsets.bottom),
),
viewInsets: viewInsets.copyWith( viewInsets: viewInsets.copyWith(
left: removeLeft ? 0.0 : null, left: removeLeft ? 0.0 : null,
top: removeTop ? 0.0 : null, top: removeTop ? 0.0 : null,
...@@ -322,6 +392,53 @@ class MediaQueryData { ...@@ -322,6 +392,53 @@ class MediaQueryData {
); );
} }
/// Creates a copy of this media query data but with the given [viewPadding]
/// replaced with zero.
///
/// The `removeLeft`, `removeTop`, `removeRight`, and `removeBottom` arguments
/// must not be null. If all four are false (the default) then this
/// [MediaQueryData] is returned unmodified.
///
/// See also:
///
/// * [new MediaQuery.removeViewPadding], which uses this method to remove
/// padding from the ambient [MediaQuery].
/// * [removePadding], the same thing but for [padding].
/// * [removeViewInsets], the same thing but for [viewInsets].
MediaQueryData removeViewPadding({
bool removeLeft = false,
bool removeTop = false,
bool removeRight = false,
bool removeBottom = false,
}) {
if (!(removeLeft || removeTop || removeRight || removeBottom))
return this;
return MediaQueryData(
size: size,
devicePixelRatio: devicePixelRatio,
textScaleFactor: textScaleFactor,
platformBrightness: platformBrightness,
padding: padding.copyWith(
left: removeLeft ? 0.0 : null,
top: removeTop ? 0.0 : null,
right: removeRight ? 0.0 : null,
bottom: removeBottom ? 0.0 : null,
),
viewInsets: viewInsets,
viewPadding: viewPadding.copyWith(
left: removeLeft ? 0.0 : null,
top: removeTop ? 0.0 : null,
right: removeRight ? 0.0 : null,
bottom: removeBottom ? 0.0 : null,
),
alwaysUse24HourFormat: alwaysUse24HourFormat,
disableAnimations: disableAnimations,
invertColors: invertColors,
accessibleNavigation: accessibleNavigation,
boldText: boldText,
);
}
@override @override
bool operator ==(Object other) { bool operator ==(Object other) {
if (other.runtimeType != runtimeType) if (other.runtimeType != runtimeType)
...@@ -332,6 +449,7 @@ class MediaQueryData { ...@@ -332,6 +449,7 @@ class MediaQueryData {
&& typedOther.textScaleFactor == textScaleFactor && typedOther.textScaleFactor == textScaleFactor
&& typedOther.platformBrightness == platformBrightness && typedOther.platformBrightness == platformBrightness
&& typedOther.padding == padding && typedOther.padding == padding
&& typedOther.viewPadding == viewPadding
&& typedOther.viewInsets == viewInsets && typedOther.viewInsets == viewInsets
&& typedOther.alwaysUse24HourFormat == alwaysUse24HourFormat && typedOther.alwaysUse24HourFormat == alwaysUse24HourFormat
&& typedOther.disableAnimations == disableAnimations && typedOther.disableAnimations == disableAnimations
...@@ -348,6 +466,7 @@ class MediaQueryData { ...@@ -348,6 +466,7 @@ class MediaQueryData {
textScaleFactor, textScaleFactor,
platformBrightness, platformBrightness,
padding, padding,
viewPadding,
viewInsets, viewInsets,
alwaysUse24HourFormat, alwaysUse24HourFormat,
disableAnimations, disableAnimations,
...@@ -365,6 +484,7 @@ class MediaQueryData { ...@@ -365,6 +484,7 @@ class MediaQueryData {
'textScaleFactor: ${textScaleFactor.toStringAsFixed(1)}, ' 'textScaleFactor: ${textScaleFactor.toStringAsFixed(1)}, '
'platformBrightness: $platformBrightness, ' 'platformBrightness: $platformBrightness, '
'padding: $padding, ' 'padding: $padding, '
'viewPadding: $viewPadding, '
'viewInsets: $viewInsets, ' 'viewInsets: $viewInsets, '
'alwaysUse24HourFormat: $alwaysUse24HourFormat, ' 'alwaysUse24HourFormat: $alwaysUse24HourFormat, '
'accessibleNavigation: $accessibleNavigation, ' 'accessibleNavigation: $accessibleNavigation, '
...@@ -430,6 +550,7 @@ class MediaQuery extends InheritedWidget { ...@@ -430,6 +550,7 @@ class MediaQuery extends InheritedWidget {
/// adds a [Padding] widget. /// adds a [Padding] widget.
/// * [MediaQueryData.padding], the affected property of the [MediaQueryData]. /// * [MediaQueryData.padding], the affected property of the [MediaQueryData].
/// * [new removeViewInsets], the same thing but for removing view insets. /// * [new removeViewInsets], the same thing but for removing view insets.
/// * [new removeViewPadding], the same thing but for removing view insets.
factory MediaQuery.removePadding({ factory MediaQuery.removePadding({
Key key, Key key,
@required BuildContext context, @required BuildContext context,
...@@ -472,6 +593,7 @@ class MediaQuery extends InheritedWidget { ...@@ -472,6 +593,7 @@ class MediaQuery extends InheritedWidget {
/// ///
/// * [MediaQueryData.viewInsets], the affected property of the [MediaQueryData]. /// * [MediaQueryData.viewInsets], the affected property of the [MediaQueryData].
/// * [new removePadding], the same thing but for removing paddings. /// * [new removePadding], the same thing but for removing paddings.
/// * [new removeViewPadding], the same thing but for removing view insets.
factory MediaQuery.removeViewInsets({ factory MediaQuery.removeViewInsets({
Key key, Key key,
@required BuildContext context, @required BuildContext context,
...@@ -493,6 +615,50 @@ class MediaQuery extends InheritedWidget { ...@@ -493,6 +615,50 @@ class MediaQuery extends InheritedWidget {
); );
} }
/// Creates a new [MediaQuery] that inherits from the ambient [MediaQuery] from
/// the given context, but removes the specified view padding.
///
/// This should be inserted into the widget tree when the [MediaQuery] view
/// padding is consumed by a widget in such a way that the view padding is no
/// longer exposed to the widget's descendants or siblings.
///
/// The [context] argument is required, must not be null, and must have a
/// [MediaQuery] in scope.
///
/// The `removeLeft`, `removeTop`, `removeRight`, and `removeBottom` arguments
/// must not be null. If all four are false (the default) then the returned
/// [MediaQuery] reuses the ambient [MediaQueryData] unmodified, which is not
/// particularly useful.
///
/// The [child] argument is required and must not be null.
///
/// See also:
///
/// * [MediaQueryData.viewPadding], the affected property of the
/// [MediaQueryData].
/// * [new removePadding], the same thing but for removing paddings.
/// * [new removeViewInsets], the same thing but for removing view insets.
factory MediaQuery.removeViewPadding({
Key key,
@required BuildContext context,
bool removeLeft = false,
bool removeTop = false,
bool removeRight = false,
bool removeBottom = false,
@required Widget child,
}) {
return MediaQuery(
key: key,
data: MediaQuery.of(context).removeViewPadding(
removeLeft: removeLeft,
removeTop: removeTop,
removeRight: removeRight,
removeBottom: removeBottom,
),
child: child,
);
}
/// Contains information about the current media. /// Contains information about the current media.
/// ///
/// For example, the [MediaQueryData.size] property contains the width and /// For example, the [MediaQueryData.size] property contains the width and
......
...@@ -56,6 +56,7 @@ void main() { ...@@ -56,6 +56,7 @@ void main() {
expect(copied.devicePixelRatio, data.devicePixelRatio); expect(copied.devicePixelRatio, data.devicePixelRatio);
expect(copied.textScaleFactor, data.textScaleFactor); expect(copied.textScaleFactor, data.textScaleFactor);
expect(copied.padding, data.padding); expect(copied.padding, data.padding);
expect(copied.viewPadding, data.viewPadding);
expect(copied.viewInsets, data.viewInsets); expect(copied.viewInsets, data.viewInsets);
expect(copied.alwaysUse24HourFormat, data.alwaysUse24HourFormat); expect(copied.alwaysUse24HourFormat, data.alwaysUse24HourFormat);
expect(copied.accessibleNavigation, data.accessibleNavigation); expect(copied.accessibleNavigation, data.accessibleNavigation);
...@@ -72,6 +73,7 @@ void main() { ...@@ -72,6 +73,7 @@ void main() {
devicePixelRatio: 1.41, devicePixelRatio: 1.41,
textScaleFactor: 1.62, textScaleFactor: 1.62,
padding: const EdgeInsets.all(9.10938), padding: const EdgeInsets.all(9.10938),
viewPadding: const EdgeInsets.all(11.24031),
viewInsets: const EdgeInsets.all(1.67262), viewInsets: const EdgeInsets.all(1.67262),
alwaysUse24HourFormat: true, alwaysUse24HourFormat: true,
accessibleNavigation: true, accessibleNavigation: true,
...@@ -84,6 +86,7 @@ void main() { ...@@ -84,6 +86,7 @@ void main() {
expect(copied.devicePixelRatio, 1.41); expect(copied.devicePixelRatio, 1.41);
expect(copied.textScaleFactor, 1.62); expect(copied.textScaleFactor, 1.62);
expect(copied.padding, const EdgeInsets.all(9.10938)); expect(copied.padding, const EdgeInsets.all(9.10938));
expect(copied.viewPadding, const EdgeInsets.all(11.24031));
expect(copied.viewInsets, const EdgeInsets.all(1.67262)); expect(copied.viewInsets, const EdgeInsets.all(1.67262));
expect(copied.alwaysUse24HourFormat, true); expect(copied.alwaysUse24HourFormat, true);
expect(copied.accessibleNavigation, true); expect(copied.accessibleNavigation, true);
...@@ -98,6 +101,7 @@ void main() { ...@@ -98,6 +101,7 @@ void main() {
const double devicePixelRatio = 2.0; const double devicePixelRatio = 2.0;
const double textScaleFactor = 1.2; const double textScaleFactor = 1.2;
const EdgeInsets padding = EdgeInsets.only(top: 1.0, right: 2.0, left: 3.0, bottom: 4.0); const EdgeInsets padding = EdgeInsets.only(top: 1.0, right: 2.0, left: 3.0, bottom: 4.0);
const EdgeInsets viewPadding = EdgeInsets.only(top: 6.0, right: 8.0, left: 10.0, bottom: 12.0);
const EdgeInsets viewInsets = EdgeInsets.only(top: 5.0, right: 6.0, left: 7.0, bottom: 8.0); const EdgeInsets viewInsets = EdgeInsets.only(top: 5.0, right: 6.0, left: 7.0, bottom: 8.0);
MediaQueryData unpadded; MediaQueryData unpadded;
...@@ -108,6 +112,7 @@ void main() { ...@@ -108,6 +112,7 @@ void main() {
devicePixelRatio: devicePixelRatio, devicePixelRatio: devicePixelRatio,
textScaleFactor: textScaleFactor, textScaleFactor: textScaleFactor,
padding: padding, padding: padding,
viewPadding: viewPadding,
viewInsets: viewInsets, viewInsets: viewInsets,
alwaysUse24HourFormat: true, alwaysUse24HourFormat: true,
accessibleNavigation: true, accessibleNavigation: true,
...@@ -139,6 +144,7 @@ void main() { ...@@ -139,6 +144,7 @@ void main() {
expect(unpadded.devicePixelRatio, devicePixelRatio); expect(unpadded.devicePixelRatio, devicePixelRatio);
expect(unpadded.textScaleFactor, textScaleFactor); expect(unpadded.textScaleFactor, textScaleFactor);
expect(unpadded.padding, EdgeInsets.zero); expect(unpadded.padding, EdgeInsets.zero);
expect(unpadded.viewPadding, viewInsets);
expect(unpadded.viewInsets, viewInsets); expect(unpadded.viewInsets, viewInsets);
expect(unpadded.alwaysUse24HourFormat, true); expect(unpadded.alwaysUse24HourFormat, true);
expect(unpadded.accessibleNavigation, true); expect(unpadded.accessibleNavigation, true);
...@@ -152,6 +158,7 @@ void main() { ...@@ -152,6 +158,7 @@ void main() {
const double devicePixelRatio = 2.0; const double devicePixelRatio = 2.0;
const double textScaleFactor = 1.2; const double textScaleFactor = 1.2;
const EdgeInsets padding = EdgeInsets.only(top: 5.0, right: 6.0, left: 7.0, bottom: 8.0); const EdgeInsets padding = EdgeInsets.only(top: 5.0, right: 6.0, left: 7.0, bottom: 8.0);
const EdgeInsets viewPadding = EdgeInsets.only(top: 6.0, right: 8.0, left: 10.0, bottom: 12.0);
const EdgeInsets viewInsets = EdgeInsets.only(top: 1.0, right: 2.0, left: 3.0, bottom: 4.0); const EdgeInsets viewInsets = EdgeInsets.only(top: 1.0, right: 2.0, left: 3.0, bottom: 4.0);
MediaQueryData unpadded; MediaQueryData unpadded;
...@@ -162,6 +169,7 @@ void main() { ...@@ -162,6 +169,7 @@ void main() {
devicePixelRatio: devicePixelRatio, devicePixelRatio: devicePixelRatio,
textScaleFactor: textScaleFactor, textScaleFactor: textScaleFactor,
padding: padding, padding: padding,
viewPadding : viewPadding,
viewInsets: viewInsets, viewInsets: viewInsets,
alwaysUse24HourFormat: true, alwaysUse24HourFormat: true,
accessibleNavigation: true, accessibleNavigation: true,
...@@ -193,6 +201,7 @@ void main() { ...@@ -193,6 +201,7 @@ void main() {
expect(unpadded.devicePixelRatio, devicePixelRatio); expect(unpadded.devicePixelRatio, devicePixelRatio);
expect(unpadded.textScaleFactor, textScaleFactor); expect(unpadded.textScaleFactor, textScaleFactor);
expect(unpadded.padding, padding); expect(unpadded.padding, padding);
expect(unpadded.viewPadding, padding);
expect(unpadded.viewInsets, EdgeInsets.zero); expect(unpadded.viewInsets, EdgeInsets.zero);
expect(unpadded.alwaysUse24HourFormat, true); expect(unpadded.alwaysUse24HourFormat, true);
expect(unpadded.accessibleNavigation, true); expect(unpadded.accessibleNavigation, true);
...@@ -201,6 +210,63 @@ void main() { ...@@ -201,6 +210,63 @@ void main() {
expect(unpadded.boldText, true); expect(unpadded.boldText, true);
}); });
testWidgets('MediaQuery.removeViewPadding removes specified viewPadding', (WidgetTester tester) async {
const Size size = Size(2.0, 4.0);
const double devicePixelRatio = 2.0;
const double textScaleFactor = 1.2;
const EdgeInsets padding = EdgeInsets.only(top: 5.0, right: 6.0, left: 7.0, bottom: 8.0);
const EdgeInsets viewPadding = EdgeInsets.only(top: 6.0, right: 8.0, left: 10.0, bottom: 12.0);
const EdgeInsets viewInsets = EdgeInsets.only(top: 1.0, right: 2.0, left: 3.0, bottom: 4.0);
MediaQueryData unpadded;
await tester.pumpWidget(
MediaQuery(
data: const MediaQueryData(
size: size,
devicePixelRatio: devicePixelRatio,
textScaleFactor: textScaleFactor,
padding: padding,
viewPadding : viewPadding,
viewInsets: viewInsets,
alwaysUse24HourFormat: true,
accessibleNavigation: true,
invertColors: true,
disableAnimations: true,
boldText: true,
),
child: Builder(
builder: (BuildContext context) {
return MediaQuery.removeViewPadding(
context: context,
removeLeft: true,
removeTop: true,
removeRight: true,
removeBottom: true,
child: Builder(
builder: (BuildContext context) {
unpadded = MediaQuery.of(context);
return Container();
}
),
);
},
),
)
);
expect(unpadded.size, size);
expect(unpadded.devicePixelRatio, devicePixelRatio);
expect(unpadded.textScaleFactor, textScaleFactor);
expect(unpadded.padding, EdgeInsets.zero);
expect(unpadded.viewPadding, EdgeInsets.zero);
expect(unpadded.viewInsets, viewInsets);
expect(unpadded.alwaysUse24HourFormat, true);
expect(unpadded.accessibleNavigation, true);
expect(unpadded.invertColors, true);
expect(unpadded.disableAnimations, true);
expect(unpadded.boldText, true);
});
testWidgets('MediaQuery.textScaleFactorOf', (WidgetTester tester) async { testWidgets('MediaQuery.textScaleFactorOf', (WidgetTester tester) async {
double outsideTextScaleFactor; double outsideTextScaleFactor;
double insideTextScaleFactor; double insideTextScaleFactor;
......
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