Unverified Commit a152a209 authored by Hans Muller's avatar Hans Muller Committed by GitHub

Deprecate Scaffold resizeToAvoidBottomPadding, now resizeToAvoidBottomInset (#26259)

parent 3a694a6d
...@@ -30,6 +30,25 @@ enum Orientation { ...@@ -30,6 +30,25 @@ enum Orientation {
/// If no [MediaQuery] is in scope then the [MediaQuery.of] method will throw an /// If no [MediaQuery] is in scope then the [MediaQuery.of] method will throw an
/// 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:
/// [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
/// 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.
///
/// Widgets whose layouts consume space defined by [viewInsets] or
/// [padding] shoud enclose their children in secondary MediaQuery
/// widgets that reduce those properties by the same amount.
/// The [removePadding] and [removeInsets] methods are useful for this.
@immutable @immutable
class MediaQueryData { class MediaQueryData {
/// Creates data for a media query with explicit values. /// Creates data for a media query with explicit values.
...@@ -67,7 +86,7 @@ class MediaQueryData { ...@@ -67,7 +86,7 @@ class MediaQueryData {
boldText = window.accessibilityFeatures.boldText, boldText = window.accessibilityFeatures.boldText,
alwaysUse24HourFormat = window.alwaysUse24HourFormat; alwaysUse24HourFormat = window.alwaysUse24HourFormat;
/// The size of the media in logical pixel (e.g, the size of the screen). /// The size of the media in logical pixels (e.g, the size of the screen).
/// ///
/// Logical pixels are roughly the same visual size across devices. Physical /// Logical pixels are roughly the same visual size across devices. Physical
/// pixels are the size of the actual hardware pixels on the device. The /// pixels are the size of the actual hardware pixels on the device. The
...@@ -91,17 +110,25 @@ class MediaQueryData { ...@@ -91,17 +110,25 @@ class MediaQueryData {
/// textScaleFactor defined for a [BuildContext]. /// textScaleFactor defined for a [BuildContext].
final double textScaleFactor; final double textScaleFactor;
/// The number of physical pixels on each side of the display rectangle into /// The parts of the display that are completely obscured by system UI,
/// which the application can render, but over which the operating system /// typically by the device's keyboard.
/// will likely place system UI, such as the keyboard, that fully obscures ///
/// any content. /// When a mobile device's keyboard is visible `viewInsets.bottom`
/// corresponds to the top of the keyboard.
///
/// This value is independent of the [padding]: both 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 (often the mobile device screen) that contains the app.
///
/// See also:
///
/// * [MediaQueryData], which provides some additional detail about this
/// property and how it differs from [padding].
final EdgeInsets viewInsets; final EdgeInsets viewInsets;
/// The number of physical pixels on each side of the display rectangle into /// The parts of the display that are partially obscured by system UI,
/// which the application can render, but which may be partially obscured by /// typically by the hardware display "notches" or the system status bar.
/// system UI (such as the system notification area), or or physical
/// intrusions in the display (e.g. overscan regions on television screens or
/// phone sensor housings).
/// ///
/// If you consumed this padding (e.g. by building a widget that envelops or /// If you consumed this padding (e.g. by building a widget that envelops or
/// accounts for this padding in its layout in such a way that children are /// accounts for this padding in its layout in such a way that children are
...@@ -111,6 +138,8 @@ class MediaQueryData { ...@@ -111,6 +138,8 @@ class MediaQueryData {
/// ///
/// See also: /// See also:
/// ///
/// * [MediaQueryData], which provides some additional detail about this
/// property and how it differs from [viewInsets].
/// * [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;
......
...@@ -59,7 +59,20 @@ void main() { ...@@ -59,7 +59,20 @@ void main() {
child: Scaffold( child: Scaffold(
appBar: AppBar(title: const Text('Title')), appBar: AppBar(title: const Text('Title')),
body: Container(key: bodyKey), body: Container(key: bodyKey),
resizeToAvoidBottomPadding: false, resizeToAvoidBottomInset: false,
),
)));
bodyBox = tester.renderObject(find.byKey(bodyKey));
expect(bodyBox.size, equals(const Size(800.0, 544.0)));
// Backwards compatiblity: deprecated resizeToAvoidBottomPadding flag
await tester.pumpWidget(boilerplate(MediaQuery(
data: const MediaQueryData(viewInsets: EdgeInsets.only(bottom: 100.0)),
child: Scaffold(
appBar: AppBar(title: const Text('Title')),
body: Container(key: bodyKey),
resizeToAvoidBottomPadding: false, // ignore: deprecated_member_use
), ),
))); )));
...@@ -1200,6 +1213,58 @@ void main() { ...@@ -1200,6 +1213,58 @@ void main() {
expect(scaffoldState.isDrawerOpen, true); expect(scaffoldState.isDrawerOpen, true);
}); });
}); });
testWidgets('Nested scaffold body insets', (WidgetTester tester) async {
// Regression test for https://github.com/flutter/flutter/issues/20295
final Key bodyKey = UniqueKey();
Widget buildFrame(bool innerResizeToAvoidBottomInset, bool outerResizeToAvoidBottomInset) {
return Directionality(
textDirection: TextDirection.ltr,
child: MediaQuery(
data: const MediaQueryData(viewInsets: EdgeInsets.only(bottom: 100.0)),
child: Builder(
builder: (BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: outerResizeToAvoidBottomInset,
body: Builder(
builder: (BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: innerResizeToAvoidBottomInset,
body: Container(key: bodyKey),
);
},
),
);
},
),
),
);
}
await tester.pumpWidget(buildFrame(true, true));
expect(tester.getSize(find.byKey(bodyKey)), const Size(800.0, 500.0));
await tester.pumpWidget(buildFrame(false, true));
expect(tester.getSize(find.byKey(bodyKey)), const Size(800.0, 500.0));
await tester.pumpWidget(buildFrame(true, false));
expect(tester.getSize(find.byKey(bodyKey)), const Size(800.0, 500.0));
// This is the only case where the body is not bottom inset.
await tester.pumpWidget(buildFrame(false, false));
expect(tester.getSize(find.byKey(bodyKey)), const Size(800.0, 600.0));
await tester.pumpWidget(buildFrame(null, null)); // resizeToAvoidBottomInset default is true
expect(tester.getSize(find.byKey(bodyKey)), const Size(800.0, 500.0));
await tester.pumpWidget(buildFrame(null, false));
expect(tester.getSize(find.byKey(bodyKey)), const Size(800.0, 500.0));
await tester.pumpWidget(buildFrame(false, null));
expect(tester.getSize(find.byKey(bodyKey)), const Size(800.0, 500.0));
});
} }
class _GeometryListener extends StatefulWidget { class _GeometryListener extends StatefulWidget {
......
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