Unverified Commit 4b878dc6 authored by Chris Bracken's avatar Chris Bracken Committed by GitHub

Add minimum insets to SafeArea (#14505)

As a convenience, this adds a set of minimum padding to apply. The
greater of the minimum padding and the media padding is applied to each
edge.
parent 35c2267f
......@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:math' as math;
import 'package:flutter/foundation.dart';
import 'basic.dart';
......@@ -9,8 +11,8 @@ import 'debug.dart';
import 'framework.dart';
import 'media_query.dart';
/// A widget that insets its child by sufficient padding to avoid
/// intrusions by the operating system.
/// A widget that insets its child by sufficient padding to avoid intrusions by
/// the operating system.
///
/// For example, this will indent the child by enough to avoid the status bar at
/// the top of the screen.
......@@ -18,6 +20,9 @@ import 'media_query.dart';
/// It will also indent the child by the amount necessary to avoid The Notch on
/// the iPhone X, or other similar creative physical features of the display.
///
/// When a [minimum] padding is specified, the greater of the minimum padding
/// or the safe area padding will be applied.
///
/// See also:
///
/// * [SliverSafeArea], for insetting slivers to avoid operating system
......@@ -29,13 +34,15 @@ import 'media_query.dart';
class SafeArea extends StatelessWidget {
/// Creates a widget that avoids operating system interfaces.
///
/// The [left], [top], [right], and [bottom] arguments must not be null.
/// The [left], [top], [right], [bottom], and [minimum] arguments must not be
/// null.
const SafeArea({
Key key,
this.left: true,
this.top: true,
this.right: true,
this.bottom: true,
this.minimum: EdgeInsets.zero,
@required this.child,
}) : assert(left != null),
assert(top != null),
......@@ -56,6 +63,11 @@ class SafeArea extends StatelessWidget {
/// Whether to avoid system intrusions on the bottom side of the screen.
final bool bottom;
/// This minimum padding to apply.
///
/// The greater of the minimum insets and the media padding will be applied.
final EdgeInsets minimum;
/// The widget below this widget in the tree.
///
/// The padding on the [MediaQuery] for the [child] will be suitably adjusted
......@@ -70,10 +82,10 @@ class SafeArea extends StatelessWidget {
final EdgeInsets padding = MediaQuery.of(context).padding;
return new Padding(
padding: new EdgeInsets.only(
left: left ? padding.left : 0.0,
top: top ? padding.top : 0.0,
right: right ? padding.right : 0.0,
bottom: bottom ? padding.bottom : 0.0,
left: math.max(left ? padding.left : 0.0, minimum.left),
top: math.max(top ? padding.top : 0.0, minimum.top),
right: math.max(right ? padding.right : 0.0, minimum.right),
bottom: math.max(bottom ? padding.bottom : 0.0, minimum.bottom),
),
child: new MediaQuery.removePadding(
context: context,
......@@ -106,6 +118,9 @@ class SafeArea extends StatelessWidget {
/// on the iPhone X, or other similar creative physical features of the
/// display.
///
/// When a [minimum] padding is specified, the greater of the minimum padding
/// or the safe area padding will be applied.
///
/// See also:
///
/// * [SafeArea], for insetting widgets to avoid operating system intrusions.
......@@ -116,13 +131,14 @@ class SafeArea extends StatelessWidget {
class SliverSafeArea extends StatelessWidget {
/// Creates a sliver that avoids operating system interfaces.
///
/// The [left], [top], [right], and [bottom] arguments must not be null.
/// The [left], [top], [right], [bottom], and [minimum] arguments must not be null.
const SliverSafeArea({
Key key,
this.left: true,
this.top: true,
this.right: true,
this.bottom: true,
this.minimum: EdgeInsets.zero,
@required this.sliver,
}) : assert(left != null),
assert(top != null),
......@@ -143,6 +159,11 @@ class SliverSafeArea extends StatelessWidget {
/// Whether to avoid system intrusions on the bottom side of the screen.
final bool bottom;
/// This minimum padding to apply.
///
/// The greater of the minimum padding and the media padding is be applied.
final EdgeInsets minimum;
/// The sliver below this sliver in the tree.
///
/// The padding on the [MediaQuery] for the [sliver] will be suitably adjusted
......@@ -155,10 +176,10 @@ class SliverSafeArea extends StatelessWidget {
final EdgeInsets padding = MediaQuery.of(context).padding;
return new SliverPadding(
padding: new EdgeInsets.only(
left: left ? padding.left : 0.0,
top: top ? padding.top : 0.0,
right: right ? padding.right : 0.0,
bottom: bottom ? padding.bottom : 0.0,
left: math.max(left ? padding.left : 0.0, minimum.left),
top: math.max(top ? padding.top : 0.0, minimum.top),
right: math.max(right ? padding.right : 0.0, minimum.right),
bottom: math.max(bottom ? padding.bottom : 0.0, minimum.bottom),
),
sliver: new MediaQuery.removePadding(
context: context,
......
......@@ -22,6 +22,21 @@ void main() {
expect(tester.getBottomRight(find.byType(Placeholder)), const Offset(780.0, 580.0));
});
testWidgets('SafeArea - with minimums', (WidgetTester tester) async {
await tester.pumpWidget(
const MediaQuery(
data: const MediaQueryData(padding: const EdgeInsets.all(20.0)),
child: const SafeArea(
top: false,
minimum: const EdgeInsets.fromLTRB(0.0, 10.0, 20.0, 30.0),
child: const Placeholder(),
),
),
);
expect(tester.getTopLeft(find.byType(Placeholder)), const Offset(20.0, 10.0));
expect(tester.getBottomRight(find.byType(Placeholder)), const Offset(780.0, 570.0));
});
testWidgets('SafeArea - nested', (WidgetTester tester) async {
await tester.pumpWidget(
const MediaQuery(
......@@ -119,6 +134,24 @@ void main() {
]);
});
testWidgets('SliverSafeArea - basic', (WidgetTester tester) async {
await tester.pumpWidget(
buildWidget(
const EdgeInsets.all(20.0),
const SliverSafeArea(
top: false,
minimum: const EdgeInsets.fromLTRB(0.0, 10.0, 20.0, 30.0),
sliver: const SliverToBoxAdapter(child: const SizedBox(width: 800.0, height: 100.0, child: const Text('padded'))),
),
),
);
verify(tester, <Rect>[
new Rect.fromLTWH(0.0, 0.0, 800.0, 100.0),
new Rect.fromLTWH(20.0, 110.0, 760.0, 100.0),
new Rect.fromLTWH(0.0, 240.0, 800.0, 100.0),
]);
});
testWidgets('SliverSafeArea - nested', (WidgetTester tester) async {
await tester.pumpWidget(
buildWidget(
......
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