Commit 8d41fa78 authored by gspencergoog's avatar gspencergoog Committed by GitHub

Adding proper accommodation for textScaleFactor in bottom navigation bar. (#12421)

This updates the bottom navigation bar to be able to handle more general widgets in the place of the label in the bottom navigation bar, so that Text with a textScaleFactor larger than 1.0 will behave nicely in a bottom navigation bar.

It also means that other widgets given instead of a Text widget for the label will work more predictably.

I also vastly simplified the layout logic, eliminating many computations that were not needed, and refactored the build function to use a separate private navigation tile widget.

Also, the color splash animations were coming from the wrong location (they were coming from far to the right of the touched widget), so that works as specified now.
parent 0a85db29
...@@ -8,7 +8,7 @@ import 'package:flutter/painting.dart'; ...@@ -8,7 +8,7 @@ import 'package:flutter/painting.dart';
const double kToolbarHeight = 56.0; const double kToolbarHeight = 56.0;
/// The height of the bottom navigation bar. /// The height of the bottom navigation bar.
const double kBottomNavigationBarHeight = 60.0; const double kBottomNavigationBarHeight = 56.0;
/// The height of a tab bar containing text. /// The height of a tab bar containing text.
const double kTextTabBarHeight = 48.0; const double kTextTabBarHeight = 48.0;
......
...@@ -1201,12 +1201,12 @@ class Align extends SingleChildRenderObjectWidget { ...@@ -1201,12 +1201,12 @@ class Align extends SingleChildRenderObjectWidget {
/// with the center of the parent. /// with the center of the parent.
final AlignmentGeometry alignment; final AlignmentGeometry alignment;
/// If non-null, sets its width to the child's width multipled by this factor. /// If non-null, sets its width to the child's width multiplied by this factor.
/// ///
/// Can be both greater and less than 1.0 but must be positive. /// Can be both greater and less than 1.0 but must be positive.
final double widthFactor; final double widthFactor;
/// If non-null, sets its height to the child's height multipled by this factor. /// If non-null, sets its height to the child's height multiplied by this factor.
/// ///
/// Can be both greater and less than 1.0 but must be positive. /// Can be both greater and less than 1.0 but must be positive.
final double heightFactor; final double heightFactor;
...@@ -3408,7 +3408,7 @@ class Flexible extends ParentDataWidget<Flex> { ...@@ -3408,7 +3408,7 @@ class Flexible extends ParentDataWidget<Flex> {
/// Using an [Expanded] widget makes a child of a [Row], [Column], or [Flex] /// Using an [Expanded] widget makes a child of a [Row], [Column], or [Flex]
/// expand to fill the available space in the main axis (e.g., horizontally for /// expand to fill the available space in the main axis (e.g., horizontally for
/// a [Row] or vertically for a [Column]). If multiple children are expanded, /// a [Row] or vertically for a [Column]). If multiple children are expanded,
/// the available space is divided amoung them according to the [flex] factor. /// the available space is divided among them according to the [flex] factor.
/// ///
/// An [Expanded] widget must be a descendant of a [Row], [Column], or [Flex], /// An [Expanded] widget must be a descendant of a [Row], [Column], or [Flex],
/// and the path from the [Expanded] widget to its enclosing [Row], [Column], or /// and the path from the [Expanded] widget to its enclosing [Row], [Column], or
......
...@@ -11,7 +11,7 @@ import 'framework.dart'; ...@@ -11,7 +11,7 @@ import 'framework.dart';
/// An interactive button within either material's [BottomNavigationBar] /// An interactive button within either material's [BottomNavigationBar]
/// or the iOS themed [CupertinoTabBar] with an icon and title. /// or the iOS themed [CupertinoTabBar] with an icon and title.
/// ///
/// This calss is rarely used in isolation. Commonly embedded in one of the /// This class is rarely used in isolation. Commonly embedded in one of the
/// bottom navigation widgets above. /// bottom navigation widgets above.
/// ///
/// See also: /// See also:
......
...@@ -57,7 +57,7 @@ void main() { ...@@ -57,7 +57,7 @@ void main() {
); );
final RenderBox box = tester.renderObject(find.byType(BottomNavigationBar)); final RenderBox box = tester.renderObject(find.byType(BottomNavigationBar));
expect(box.size.height, 60.0); expect(box.size.height, kBottomNavigationBarHeight);
expect(find.text('AC'), findsOneWidget); expect(find.text('AC'), findsOneWidget);
expect(find.text('Alarm'), findsOneWidget); expect(find.text('Alarm'), findsOneWidget);
}); });
...@@ -85,8 +85,8 @@ void main() { ...@@ -85,8 +85,8 @@ void main() {
Iterable<RenderBox> actions = tester.renderObjectList(find.byType(InkResponse)); Iterable<RenderBox> actions = tester.renderObjectList(find.byType(InkResponse));
expect(actions.length, 2); expect(actions.length, 2);
expect(actions.elementAt(0).size.width, 158.4); expect(actions.elementAt(0).size.width, 480.0);
expect(actions.elementAt(1).size.width, 105.6); expect(actions.elementAt(1).size.width, 320.0);
await tester.pumpWidget( await tester.pumpWidget(
new MaterialApp( new MaterialApp(
...@@ -113,8 +113,8 @@ void main() { ...@@ -113,8 +113,8 @@ void main() {
actions = tester.renderObjectList(find.byType(InkResponse)); actions = tester.renderObjectList(find.byType(InkResponse));
expect(actions.length, 2); expect(actions.length, 2);
expect(actions.elementAt(0).size.width, 105.6); expect(actions.elementAt(0).size.width, 320.0);
expect(actions.elementAt(1).size.width, 158.4); expect(actions.elementAt(1).size.width, 480.0);
}); });
testWidgets('BottomNavigationBar multiple taps test', (WidgetTester tester) async { testWidgets('BottomNavigationBar multiple taps test', (WidgetTester tester) async {
...@@ -288,4 +288,108 @@ void main() { ...@@ -288,4 +288,108 @@ void main() {
}); });
testWidgets('BottomNavigationBar responds to textScaleFactor', (WidgetTester tester) async {
await tester.pumpWidget(
new MaterialApp(
home: new Scaffold(
bottomNavigationBar: new BottomNavigationBar(
type: BottomNavigationBarType.fixed,
items: <BottomNavigationBarItem>[
const BottomNavigationBarItem(
title: const Text('A'),
icon: const Icon(Icons.ac_unit),
),
const BottomNavigationBarItem(
title: const Text('B'),
icon: const Icon(Icons.battery_alert),
),
],
),
),
),
);
final RenderBox defaultBox = tester.renderObject(find.byType(BottomNavigationBar));
expect(defaultBox.size.height, equals(kBottomNavigationBarHeight));
await tester.pumpWidget(
new MaterialApp(
home: new Scaffold(
bottomNavigationBar: new BottomNavigationBar(
type: BottomNavigationBarType.shifting,
items: <BottomNavigationBarItem>[
const BottomNavigationBarItem(
title: const Text('A'),
icon: const Icon(Icons.ac_unit),
),
const BottomNavigationBarItem(
title: const Text('B'),
icon: const Icon(Icons.battery_alert),
),
],
),
),
),
);
final RenderBox shiftingBox = tester.renderObject(find.byType(BottomNavigationBar));
expect(shiftingBox.size.height, equals(kBottomNavigationBarHeight));
await tester.pumpWidget(
new MaterialApp(
home: new MediaQuery(
data: const MediaQueryData(textScaleFactor: 2.0),
child: new Scaffold(
bottomNavigationBar: new BottomNavigationBar(
items: <BottomNavigationBarItem>[
const BottomNavigationBarItem(
title: const Text('A'),
icon: const Icon(Icons.ac_unit),
),
const BottomNavigationBarItem(
title: const Text('B'),
icon: const Icon(Icons.battery_alert),
),
],
),
),
),
),
);
final RenderBox box = tester.renderObject(find.byType(BottomNavigationBar));
expect(box.size.height, equals(68.0));
});
testWidgets('BottomNavigationBar limits width of tiles with long titles', (WidgetTester tester) async {
final Text longTextA = new Text(''.padLeft(100, 'A'));
final Text longTextB = new Text(''.padLeft(100, 'B'));
await tester.pumpWidget(
new MaterialApp(
home: new Scaffold(
bottomNavigationBar: new BottomNavigationBar(
items: <BottomNavigationBarItem>[
new BottomNavigationBarItem(
title: longTextA,
icon: const Icon(Icons.ac_unit),
),
new BottomNavigationBarItem(
title: longTextB,
icon: const Icon(Icons.battery_alert),
),
],
),
),
),
);
final RenderBox box = tester.renderObject(find.byType(BottomNavigationBar));
expect(box.size.height, equals(kBottomNavigationBarHeight));
final RenderBox itemBoxA = tester.renderObject(find.text(longTextA.data));
expect(itemBoxA.size, equals(const Size(400.0, 14.0)));
final RenderBox itemBoxB = tester.renderObject(find.text(longTextB.data));
expect(itemBoxB.size, equals(const Size(400.0, 14.0)));
});
} }
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