Unverified Commit 57a688c1 authored by Qun Cheng's avatar Qun Cheng Committed by GitHub

Add padding for Navigation Bar to account for safe area (#102419)

parent 4cea9afc
......@@ -147,41 +147,35 @@ class NavigationBar extends StatelessWidget {
final NavigationDestinationLabelBehavior effectiveLabelBehavior = labelBehavior
?? navigationBarTheme.labelBehavior
?? defaults.labelBehavior!;
final double additionalBottomPadding = MediaQuery.of(context).padding.bottom;
return Material(
color: backgroundColor
?? navigationBarTheme.backgroundColor
?? defaults.backgroundColor!,
elevation: elevation ?? navigationBarTheme.elevation ?? defaults.elevation!,
child: Padding(
padding: EdgeInsets.only(bottom: additionalBottomPadding),
child: MediaQuery.removePadding(
context: context,
removeBottom: true,
child: SizedBox(
height: effectiveHeight,
child: Row(
children: <Widget>[
for (int i = 0; i < destinations.length; i++)
Expanded(
child: _SelectableAnimatedBuilder(
duration: animationDuration ?? const Duration(milliseconds: 500),
isSelected: i == selectedIndex,
builder: (BuildContext context, Animation<double> animation) {
return _NavigationDestinationInfo(
index: i,
totalNumberOfDestinations: destinations.length,
selectedAnimation: animation,
labelBehavior: effectiveLabelBehavior,
onTap: _handleTap(i),
child: destinations[i],
);
},
),
child: SafeArea(
child: SizedBox(
height: effectiveHeight,
child: Row(
children: <Widget>[
for (int i = 0; i < destinations.length; i++)
Expanded(
child: _SelectableAnimatedBuilder(
duration: animationDuration ?? const Duration(milliseconds: 500),
isSelected: i == selectedIndex,
builder: (BuildContext context, Animation<double> animation) {
return _NavigationDestinationInfo(
index: i,
totalNumberOfDestinations: destinations.length,
selectedAnimation: animation,
labelBehavior: effectiveLabelBehavior,
onTap: _handleTap(i),
child: destinations[i],
);
},
),
],
),
),
],
),
),
),
......
......@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
......@@ -137,6 +138,104 @@ void main() {
expect(tester.getSize(find.byType(NavigationBar)).height, expectedHeight);
});
testWidgets('NavigationBar respects the notch/system navigation bar in landscape mode', (WidgetTester tester) async {
const double safeAreaPadding = 40.0;
Widget navigationBar() {
return NavigationBar(
destinations: const <Widget>[
NavigationDestination(
icon: Icon(Icons.ac_unit),
label: 'AC',
),
NavigationDestination(
key: Key('Center'),
icon: Icon(Icons.center_focus_strong),
label: 'Center',
),
NavigationDestination(
icon: Icon(Icons.access_alarm),
label: 'Alarm',
),
],
onDestinationSelected: (int i) {},
);
}
await tester.pumpWidget(_buildWidget(navigationBar()));
final double defaultWidth = tester.getSize(find.byType(NavigationBar)).width;
final Finder defaultCenterItem = find.byKey(const Key('Center'));
final Offset center = tester.getCenter(defaultCenterItem);
expect(center.dx, defaultWidth / 2);
await tester.pumpWidget(
_buildWidget(
MediaQuery(
data: const MediaQueryData(
padding: EdgeInsets.only(left: safeAreaPadding),
),
child: navigationBar(),
),
),
);
// The position of center item of navigation bar should indicate whether
// the safe area is sufficiently respected, when safe area is on the left side.
// e.g. Android device with system navigation bar in landscape mode.
final Finder leftPaddedCenterItem = find.byKey(const Key('Center'));
final Offset leftPaddedCenter = tester.getCenter(leftPaddedCenterItem);
expect(
leftPaddedCenter.dx,
closeTo((defaultWidth + safeAreaPadding) / 2.0, precisionErrorTolerance),
);
await tester.pumpWidget(
_buildWidget(
MediaQuery(
data: const MediaQueryData(
padding: EdgeInsets.only(right: safeAreaPadding)
),
child: navigationBar(),
),
),
);
// The position of center item of navigation bar should indicate whether
// the safe area is sufficiently respected, when safe area is on the right side.
// e.g. Android device with system navigation bar in landscape mode.
final Finder rightPaddedCenterItem = find.byKey(const Key('Center'));
final Offset rightPaddedCenter = tester.getCenter(rightPaddedCenterItem);
expect(
rightPaddedCenter.dx,
closeTo((defaultWidth - safeAreaPadding) / 2, precisionErrorTolerance),
);
await tester.pumpWidget(
_buildWidget(
MediaQuery(
data: const MediaQueryData(
padding: EdgeInsets.fromLTRB(
safeAreaPadding,
0,
safeAreaPadding,
safeAreaPadding
),
),
child: navigationBar(),
),
),
);
// The position of center item of navigation bar should indicate whether
// the safe area is sufficiently respected, when safe areas are on both sides.
// e.g. iOS device with both sides of round corner.
final Finder paddedCenterItem = find.byKey(const Key('Center'));
final Offset paddedCenter = tester.getCenter(paddedCenterItem);
expect(
paddedCenter.dx,
closeTo(defaultWidth / 2, precisionErrorTolerance),
);
});
testWidgets('NavigationBar uses proper defaults when no parameters are given', (WidgetTester tester) async {
// Pre-M3 settings that were hand coded.
await tester.pumpWidget(
......
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