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.
This commit is contained in:
parent
35c2267ffe
commit
4b878dc687
@ -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(
|
||||
|
Loading…
x
Reference in New Issue
Block a user