Unverified Commit e0817715 authored by xster's avatar xster Committed by GitHub

Put the nav bar padding inside the CustomMultiChildLayout for correct...

Put the nav bar padding inside the CustomMultiChildLayout for correct centering and allow custom padding (#19129)
parent 5c8d7e34
...@@ -26,9 +26,6 @@ const double _kNavBarShowLargeTitleThreshold = 10.0; ...@@ -26,9 +26,6 @@ const double _kNavBarShowLargeTitleThreshold = 10.0;
const double _kNavBarEdgePadding = 16.0; const double _kNavBarEdgePadding = 16.0;
// The back chevron has a special padding in iOS.
const double _kNavBarBackButtonPadding = 0.0;
const double _kNavBarBackButtonTapWidth = 50.0; const double _kNavBarBackButtonTapWidth = 50.0;
/// Title text transfer fade. /// Title text transfer fade.
...@@ -87,6 +84,7 @@ class CupertinoNavigationBar extends StatelessWidget implements ObstructingPrefe ...@@ -87,6 +84,7 @@ class CupertinoNavigationBar extends StatelessWidget implements ObstructingPrefe
this.trailing, this.trailing,
this.border = _kDefaultNavBarBorder, this.border = _kDefaultNavBarBorder,
this.backgroundColor = _kDefaultNavBarBackgroundColor, this.backgroundColor = _kDefaultNavBarBackgroundColor,
this.padding,
this.actionsForegroundColor = CupertinoColors.activeBlue, this.actionsForegroundColor = CupertinoColors.activeBlue,
}) : assert(automaticallyImplyLeading != null), }) : assert(automaticallyImplyLeading != null),
super(key: key); super(key: key);
...@@ -118,6 +116,19 @@ class CupertinoNavigationBar extends StatelessWidget implements ObstructingPrefe ...@@ -118,6 +116,19 @@ class CupertinoNavigationBar extends StatelessWidget implements ObstructingPrefe
/// behind it. /// behind it.
final Color backgroundColor; final Color backgroundColor;
/// Padding for the contents of the navigation bar.
///
/// If null, the navigation bar will adopt the following defaults:
///
/// * Vertically, contents will be sized to the same height as the navigation
/// bar itself minus the status bar.
/// * Horizontally, padding will be 16 pixels according to iOS specifications
/// unless the leading widget is an automatically inserted back button, in
/// which case the padding will be 0.
///
/// Vertical padding won't change the height of the nav bar.
final EdgeInsetsDirectional padding;
/// The border of the navigation bar. By default renders a single pixel bottom border side. /// The border of the navigation bar. By default renders a single pixel bottom border side.
/// ///
/// If a border is null, the navigation bar will not display a border. /// If a border is null, the navigation bar will not display a border.
...@@ -149,6 +160,7 @@ class CupertinoNavigationBar extends StatelessWidget implements ObstructingPrefe ...@@ -149,6 +160,7 @@ class CupertinoNavigationBar extends StatelessWidget implements ObstructingPrefe
automaticallyImplyLeading: automaticallyImplyLeading, automaticallyImplyLeading: automaticallyImplyLeading,
middle: new Semantics(child: middle, header: true), middle: new Semantics(child: middle, header: true),
trailing: trailing, trailing: trailing,
padding: padding,
actionsForegroundColor: actionsForegroundColor, actionsForegroundColor: actionsForegroundColor,
), ),
); );
...@@ -197,6 +209,7 @@ class CupertinoSliverNavigationBar extends StatelessWidget { ...@@ -197,6 +209,7 @@ class CupertinoSliverNavigationBar extends StatelessWidget {
this.trailing, this.trailing,
this.border = _kDefaultNavBarBorder, this.border = _kDefaultNavBarBorder,
this.backgroundColor = _kDefaultNavBarBackgroundColor, this.backgroundColor = _kDefaultNavBarBackgroundColor,
this.padding,
this.actionsForegroundColor = CupertinoColors.activeBlue, this.actionsForegroundColor = CupertinoColors.activeBlue,
}) : assert(largeTitle != null), }) : assert(largeTitle != null),
assert(automaticallyImplyLeading != null), assert(automaticallyImplyLeading != null),
...@@ -246,6 +259,19 @@ class CupertinoSliverNavigationBar extends StatelessWidget { ...@@ -246,6 +259,19 @@ class CupertinoSliverNavigationBar extends StatelessWidget {
/// This widget is visible in both collapsed and expanded states. /// This widget is visible in both collapsed and expanded states.
final Widget trailing; final Widget trailing;
/// Padding for the contents of the navigation bar.
///
/// If null, the navigation bar will adopt the following defaults:
///
/// * Vertically, contents will be sized to the same height as the navigation
/// bar itself minus the status bar.
/// * Horizontally, padding will be 16 pixels according to iOS specifications
/// unless the leading widget is an automatically inserted back button, in
/// which case the padding will be 0.
///
/// Vertical padding won't change the height of the nav bar.
final EdgeInsetsDirectional padding;
/// The border of the navigation bar. By default renders a single pixel bottom border side. /// The border of the navigation bar. By default renders a single pixel bottom border side.
/// ///
/// If a border is null, the navigation bar will not display a border. /// If a border is null, the navigation bar will not display a border.
...@@ -277,6 +303,7 @@ class CupertinoSliverNavigationBar extends StatelessWidget { ...@@ -277,6 +303,7 @@ class CupertinoSliverNavigationBar extends StatelessWidget {
automaticallyImplyLeading: automaticallyImplyLeading, automaticallyImplyLeading: automaticallyImplyLeading,
middle: middle, middle: middle,
trailing: trailing, trailing: trailing,
padding: padding,
border: border, border: border,
backgroundColor: backgroundColor, backgroundColor: backgroundColor,
actionsForegroundColor: actionsForegroundColor, actionsForegroundColor: actionsForegroundColor,
...@@ -332,6 +359,7 @@ class _CupertinoPersistentNavigationBar extends StatelessWidget implements Prefe ...@@ -332,6 +359,7 @@ class _CupertinoPersistentNavigationBar extends StatelessWidget implements Prefe
this.automaticallyImplyLeading, this.automaticallyImplyLeading,
this.middle, this.middle,
this.trailing, this.trailing,
this.padding,
this.actionsForegroundColor, this.actionsForegroundColor,
this.middleVisible, this.middleVisible,
}) : super(key: key); }) : super(key: key);
...@@ -344,6 +372,8 @@ class _CupertinoPersistentNavigationBar extends StatelessWidget implements Prefe ...@@ -344,6 +372,8 @@ class _CupertinoPersistentNavigationBar extends StatelessWidget implements Prefe
final Widget trailing; final Widget trailing;
final EdgeInsetsDirectional padding;
final Color actionsForegroundColor; final Color actionsForegroundColor;
/// Whether the middle widget has a visible animated opacity. A null value /// Whether the middle widget has a visible animated opacity. A null value
...@@ -362,15 +392,29 @@ class _CupertinoPersistentNavigationBar extends StatelessWidget implements Prefe ...@@ -362,15 +392,29 @@ class _CupertinoPersistentNavigationBar extends StatelessWidget implements Prefe
color: actionsForegroundColor, color: actionsForegroundColor,
); );
final Widget styledLeading = leading == null ? null : new DefaultTextStyle( final Widget styledLeading = leading == null
style: actionsStyle, ? null
child: leading, : new Padding(
); padding: new EdgeInsetsDirectional.only(
start: padding?.start ?? _kNavBarEdgePadding,
),
child: new DefaultTextStyle(
style: actionsStyle,
child: leading,
),
);
final Widget styledTrailing = trailing == null ? null : new DefaultTextStyle( final Widget styledTrailing = trailing == null
style: actionsStyle, ? null
child: trailing, : Padding(
); padding: new EdgeInsetsDirectional.only(
end: padding?.end ?? _kNavBarEdgePadding,
),
child: new DefaultTextStyle(
style: actionsStyle,
child: trailing,
),
);
// Let the middle be black rather than `actionsForegroundColor` in case // Let the middle be black rather than `actionsForegroundColor` in case
// it's a plain text title. // it's a plain text title.
...@@ -413,6 +457,23 @@ class _CupertinoPersistentNavigationBar extends StatelessWidget implements Prefe ...@@ -413,6 +457,23 @@ class _CupertinoPersistentNavigationBar extends StatelessWidget implements Prefe
} }
} }
Widget paddedToolbar = new NavigationToolbar(
leading: styledLeading ?? backOrCloseButton,
middle: animatedStyledMiddle,
trailing: styledTrailing,
centerMiddle: true,
);
if (padding != null) {
paddedToolbar = new Padding(
padding: EdgeInsets.only(
top: padding.top,
bottom: padding.bottom,
),
child: paddedToolbar,
);
}
return new SizedBox( return new SizedBox(
height: _kNavBarPersistentHeight + MediaQuery.of(context).padding.top, height: _kNavBarPersistentHeight + MediaQuery.of(context).padding.top,
child: IconTheme.merge( child: IconTheme.merge(
...@@ -422,18 +483,7 @@ class _CupertinoPersistentNavigationBar extends StatelessWidget implements Prefe ...@@ -422,18 +483,7 @@ class _CupertinoPersistentNavigationBar extends StatelessWidget implements Prefe
), ),
child: new SafeArea( child: new SafeArea(
bottom: false, bottom: false,
child: new Padding( child: paddedToolbar,
padding: new EdgeInsetsDirectional.only(
start: useBackButton ? _kNavBarBackButtonPadding : _kNavBarEdgePadding,
end: _kNavBarEdgePadding,
),
child: new NavigationToolbar(
leading: styledLeading ?? backOrCloseButton,
middle: animatedStyledMiddle,
trailing: styledTrailing,
centerMiddle: true,
),
),
), ),
), ),
); );
...@@ -449,6 +499,7 @@ class _CupertinoLargeTitleNavigationBarSliverDelegate ...@@ -449,6 +499,7 @@ class _CupertinoLargeTitleNavigationBarSliverDelegate
this.automaticallyImplyLeading, this.automaticallyImplyLeading,
this.middle, this.middle,
this.trailing, this.trailing,
this.padding,
this.border, this.border,
this.backgroundColor, this.backgroundColor,
this.actionsForegroundColor, this.actionsForegroundColor,
...@@ -466,6 +517,8 @@ class _CupertinoLargeTitleNavigationBarSliverDelegate ...@@ -466,6 +517,8 @@ class _CupertinoLargeTitleNavigationBarSliverDelegate
final Widget trailing; final Widget trailing;
final EdgeInsetsDirectional padding;
final Color backgroundColor; final Color backgroundColor;
final Border border; final Border border;
...@@ -491,6 +544,7 @@ class _CupertinoLargeTitleNavigationBarSliverDelegate ...@@ -491,6 +544,7 @@ class _CupertinoLargeTitleNavigationBarSliverDelegate
// If middle widget exists, always show it. Otherwise, show title // If middle widget exists, always show it. Otherwise, show title
// when collapsed. // when collapsed.
middleVisible: middle != null ? null : !showLargeTitle, middleVisible: middle != null ? null : !showLargeTitle,
padding: padding,
actionsForegroundColor: actionsForegroundColor, actionsForegroundColor: actionsForegroundColor,
); );
......
...@@ -28,6 +28,30 @@ void main() { ...@@ -28,6 +28,30 @@ void main() {
expect(tester.getCenter(find.text('Title')).dx, 400.0); expect(tester.getCenter(find.text('Title')).dx, 400.0);
}); });
testWidgets('Middle still in center with back button', (WidgetTester tester) async {
await tester.pumpWidget(
new CupertinoApp(
home: const CupertinoNavigationBar(
middle: const Text('Title'),
),
),
);
tester.state<NavigatorState>(find.byType(Navigator)).push(new CupertinoPageRoute<void>(
builder: (BuildContext context) {
return const CupertinoNavigationBar(
middle: const Text('Page 2'),
);
},
));
await tester.pump();
await tester.pump(const Duration(milliseconds: 500));
// Expect the middle of the title to be exactly in the middle of the screen.
expect(tester.getCenter(find.text('Page 2')).dx, 400.0);
});
testWidgets('Opaque background does not add blur effects', (WidgetTester tester) async { testWidgets('Opaque background does not add blur effects', (WidgetTester tester) async {
await tester.pumpWidget( await tester.pumpWidget(
new CupertinoApp( new CupertinoApp(
...@@ -51,6 +75,79 @@ void main() { ...@@ -51,6 +75,79 @@ void main() {
expect(find.byType(BackdropFilter), findsOneWidget); expect(find.byType(BackdropFilter), findsOneWidget);
}); });
testWidgets('Can specify custom padding', (WidgetTester tester) async {
final Key middleBox = new GlobalKey();
await tester.pumpWidget(
new CupertinoApp(
home: new Align(
alignment: Alignment.topCenter,
child: new CupertinoNavigationBar(
leading: const CupertinoButton(child: const Text('Cheetah'), onPressed: null),
// Let the box take all the vertical space to test vertical padding but let
// the nav bar position it horizontally.
middle: new Align(
key: middleBox,
alignment: Alignment.center,
widthFactor: 1.0,
child: const Text('Title')
),
trailing: const CupertinoButton(child: const Text('Puma'), onPressed: null),
padding: const EdgeInsetsDirectional.only(
start: 10.0,
end: 20.0,
top: 3.0,
bottom: 4.0,
),
),
),
),
);
expect(tester.getRect(find.byKey(middleBox)).top, 3.0);
// 44 is the standard height of the nav bar.
expect(
tester.getRect(find.byKey(middleBox)).bottom,
// 44 is the standard height of the nav bar.
44.0 - 4.0,
);
expect(tester.getTopLeft(find.widgetWithText(CupertinoButton, 'Cheetah')).dx, 10.0);
expect(tester.getTopRight(find.widgetWithText(CupertinoButton, 'Puma')).dx, 800.0 - 20.0);
// Title is still exactly centered.
expect(tester.getCenter(find.text('Title')).dx, 400.0);
});
testWidgets('Padding works in RTL', (WidgetTester tester) async {
await tester.pumpWidget(
new CupertinoApp(
home: const Directionality(
textDirection: TextDirection.rtl,
child: const Align(
alignment: Alignment.topCenter,
child: const CupertinoNavigationBar(
leading: const CupertinoButton(child: const Text('Cheetah'), onPressed: null),
// Let the box take all the vertical space to test vertical padding but let
// the nav bar position it horizontally.
middle: const Text('Title'),
trailing: const CupertinoButton(child: const Text('Puma'), onPressed: null),
padding: const EdgeInsetsDirectional.only(
start: 10.0,
end: 20.0,
),
),
),
),
),
);
expect(tester.getTopRight(find.widgetWithText(CupertinoButton, 'Cheetah')).dx, 800.0 - 10.0);
expect(tester.getTopLeft(find.widgetWithText(CupertinoButton, 'Puma')).dx, 20.0);
// Title is still exactly centered.
expect(tester.getCenter(find.text('Title')).dx, 400.0);
});
testWidgets('Verify styles of each slot', (WidgetTester tester) async { testWidgets('Verify styles of each slot', (WidgetTester tester) async {
count = 0x000000; count = 0x000000;
await tester.pumpWidget( 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