Unverified Commit 26c30fe2 authored by Hans Muller's avatar Hans Muller Committed by GitHub

Added BottomNavigationBar landscapeLayout parameter (#87211)

parent c5866c5e
......@@ -44,6 +44,7 @@ class BottomNavigationBarThemeData with Diagnosticable {
this.showUnselectedLabels,
this.type,
this.enableFeedback,
this.landscapeLayout,
});
/// The color of the [BottomNavigationBar] itself.
......@@ -120,6 +121,9 @@ class BottomNavigationBarThemeData with Diagnosticable {
/// If [BottomNavigationBar.enableFeedback] is provided, [enableFeedback] is ignored.
final bool? enableFeedback;
/// If non-null, overrides the [BottomNavigationBar.landscapeLayout] property.
final BottomNavigationBarLandscapeLayout? landscapeLayout;
/// Creates a copy of this object but with the given fields replaced with the
/// new values.
BottomNavigationBarThemeData copyWith({
......@@ -135,6 +139,7 @@ class BottomNavigationBarThemeData with Diagnosticable {
bool? showUnselectedLabels,
BottomNavigationBarType? type,
bool? enableFeedback,
BottomNavigationBarLandscapeLayout? landscapeLayout
}) {
return BottomNavigationBarThemeData(
backgroundColor: backgroundColor ?? this.backgroundColor,
......@@ -149,6 +154,7 @@ class BottomNavigationBarThemeData with Diagnosticable {
showUnselectedLabels: showUnselectedLabels ?? this.showUnselectedLabels,
type: type ?? this.type,
enableFeedback: enableFeedback ?? this.enableFeedback,
landscapeLayout: landscapeLayout ?? this.landscapeLayout,
);
}
......@@ -172,6 +178,7 @@ class BottomNavigationBarThemeData with Diagnosticable {
showUnselectedLabels: t < 0.5 ? a?.showUnselectedLabels : b?.showUnselectedLabels,
type: t < 0.5 ? a?.type : b?.type,
enableFeedback: t < 0.5 ? a?.enableFeedback : b?.enableFeedback,
landscapeLayout: t < 0.5 ? a?.landscapeLayout : b?.landscapeLayout,
);
}
......@@ -190,6 +197,7 @@ class BottomNavigationBarThemeData with Diagnosticable {
showUnselectedLabels,
type,
enableFeedback,
landscapeLayout,
);
}
......@@ -211,7 +219,8 @@ class BottomNavigationBarThemeData with Diagnosticable {
&& other.showSelectedLabels == showSelectedLabels
&& other.showUnselectedLabels == showUnselectedLabels
&& other.type == type
&& other.enableFeedback == enableFeedback;
&& other.enableFeedback == enableFeedback
&& other.landscapeLayout == landscapeLayout;
}
@override
......@@ -229,6 +238,7 @@ class BottomNavigationBarThemeData with Diagnosticable {
properties.add(DiagnosticsProperty<bool>('showUnselectedLabels', showUnselectedLabels, defaultValue: null));
properties.add(DiagnosticsProperty<BottomNavigationBarType>('type', type, defaultValue: null));
properties.add(DiagnosticsProperty<bool>('enableFeedback', enableFeedback, defaultValue: null));
properties.add(DiagnosticsProperty<BottomNavigationBarLandscapeLayout>('landscapeLayout', landscapeLayout, defaultValue: null));
}
}
......
......@@ -2015,6 +2015,143 @@ void main() {
semantics.dispose();
});
testWidgets('BottomNavigationBar default layout', (WidgetTester tester) async {
final Key icon0 = UniqueKey();
final Key title0 = UniqueKey();
final Key icon1 = UniqueKey();
final Key title1 = UniqueKey();
await tester.pumpWidget(
MaterialApp(
home: Builder(
builder: (BuildContext context) {
return Scaffold(
bottomNavigationBar: BottomNavigationBar(
currentIndex: 0,
items: <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: SizedBox(key: icon0, width: 200, height: 10),
title: SizedBox(key: title0, width: 200, height: 10),
),
BottomNavigationBarItem(
icon: SizedBox(key: icon1, width: 200, height: 10),
title: SizedBox(key: title1, width: 200, height: 10),
),
],
),
);
},
),
),
);
expect(tester.getSize(find.byType(BottomNavigationBar)), const Size(800, kBottomNavigationBarHeight));
expect(tester.getRect(find.byType(BottomNavigationBar)), const Rect.fromLTRB(0, 600 - kBottomNavigationBarHeight, 800, 600));
// The height of the navigation bar is kBottomNavigationBarHeight = 56
// The top of the navigation bar is 600 - 56 = 544
// The top and bottom of the selected item is defined by its centered icon/label column:
// top = 544 - (56 - (10 + 10)) / 2 = 562
// bottom = top + 10 + 10 = 582
expect(tester.getRect(find.byKey(icon0)).top, 562);
expect(tester.getRect(find.byKey(title0)).bottom, 582);
// The items are horizontal padded according to
// MainAxisAlignment.spaceBetween Left/right padding is 800 - (200
// * 4) / 4 = 100. The layout of the unselected item's title is
// slightly different; not checking that here.
expect(tester.getRect(find.byKey(title0)), const Rect.fromLTRB(100, 572, 300, 582));
expect(tester.getRect(find.byKey(icon0)), const Rect.fromLTRB(100, 562, 300, 572));
expect(tester.getRect(find.byKey(icon1)), const Rect.fromLTRB(500, 562, 700, 572));
});
testWidgets('BottomNavigationBar centered landscape layout', (WidgetTester tester) async {
final Key icon0 = UniqueKey();
final Key title0 = UniqueKey();
final Key icon1 = UniqueKey();
final Key title1 = UniqueKey();
await tester.pumpWidget(
MaterialApp(
home: Builder(
builder: (BuildContext context) {
return Scaffold(
bottomNavigationBar: BottomNavigationBar(
currentIndex: 0,
landscapeLayout: BottomNavigationBarLandscapeLayout.centered,
items: <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: SizedBox(key: icon0, width: 200, height: 10),
title: SizedBox(key: title0, width: 200, height: 10),
),
BottomNavigationBarItem(
icon: SizedBox(key: icon1, width: 200, height: 10),
title: SizedBox(key: title1, width: 200, height: 10),
),
],
),
);
},
),
),
);
expect(tester.getSize(find.byType(BottomNavigationBar)), const Size(800, kBottomNavigationBarHeight));
expect(tester.getRect(find.byType(BottomNavigationBar)), const Rect.fromLTRB(0, 600 - kBottomNavigationBarHeight, 800, 600));
// The items are laid out as in the default case, within width=600
// (the "portrait" width) and the result is centered with the
// landscape width=800. So item 0's left edges are (800 - 600) / 2 +
// (600 - 400) / 4 = 150. Item 1's right edge is 800 - 150 =
// 650. The layout of the unselected item's title is slightly
// different; not checking that here.
expect(tester.getRect(find.byKey(title0)), const Rect.fromLTRB(150.0, 572.0, 350.0, 582.0));
expect(tester.getRect(find.byKey(icon0)), const Rect.fromLTRB(150, 562, 350, 572));
expect(tester.getRect(find.byKey(icon1)), const Rect.fromLTRB(450, 562, 650, 572));
});
testWidgets('BottomNavigationBar linear landscape layout', (WidgetTester tester) async {
final Key icon0 = UniqueKey();
final Key title0 = UniqueKey();
final Key icon1 = UniqueKey();
final Key title1 = UniqueKey();
await tester.pumpWidget(
MaterialApp(
home: Builder(
builder: (BuildContext context) {
return Scaffold(
bottomNavigationBar: BottomNavigationBar(
currentIndex: 0,
landscapeLayout: BottomNavigationBarLandscapeLayout.linear,
items: <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: SizedBox(key: icon0, width: 100, height: 20),
title: SizedBox(key: title0, width: 100, height: 20),
),
BottomNavigationBarItem(
icon: SizedBox(key: icon1, width: 100, height: 20),
title: SizedBox(key: title1, width: 100, height: 20),
),
],
),
);
},
),
),
);
expect(tester.getSize(find.byType(BottomNavigationBar)), const Size(800, kBottomNavigationBarHeight));
expect(tester.getRect(find.byType(BottomNavigationBar)), const Rect.fromLTRB(0, 600 - kBottomNavigationBarHeight, 800, 600));
// The items are laid out as in the default case except each
// item's icon/title is arranged in a row, with 8 pixels in
// between the icon and title. The layout of the unselected
// item's title is slightly different; not checking that here.
expect(tester.getRect(find.byKey(title0)), const Rect.fromLTRB(204, 562, 304, 582));
expect(tester.getRect(find.byKey(icon0)), const Rect.fromLTRB(96, 562, 196, 582));
expect(tester.getRect(find.byKey(icon1)), const Rect.fromLTRB(496, 562, 596, 582));
});
}
Widget boilerplate({ Widget? bottomNavigationBar, required TextDirection textDirection }) {
......
......@@ -27,6 +27,7 @@ void main() {
expect(themeData.showSelectedLabels, null);
expect(themeData.showUnselectedLabels, null);
expect(themeData.type, null);
expect(themeData.landscapeLayout, null);
const BottomNavigationBarTheme theme = BottomNavigationBarTheme(data: BottomNavigationBarThemeData(), child: SizedBox());
expect(theme.data.backgroundColor, null);
......@@ -40,6 +41,7 @@ void main() {
expect(theme.data.showSelectedLabels, null);
expect(theme.data.showUnselectedLabels, null);
expect(theme.data.type, null);
expect(themeData.landscapeLayout, null);
});
testWidgets('Default BottomNavigationBarThemeData debugFillProperties', (WidgetTester tester) async {
......@@ -175,6 +177,7 @@ void main() {
const TextStyle themeSelectedTextStyle = TextStyle(fontSize: 22);
const TextStyle themeUnselectedTextStyle = TextStyle(fontSize: 21);
const double themeElevation = 9.0;
const BottomNavigationBarLandscapeLayout themeLandscapeLayout = BottomNavigationBarLandscapeLayout.centered;
const Color backgroundColor = Color(0xFF000004);
const Color selectedItemColor = Color(0xFF000005);
......@@ -184,6 +187,7 @@ void main() {
const TextStyle selectedTextStyle = TextStyle(fontSize: 25);
const TextStyle unselectedTextStyle = TextStyle(fontSize: 26);
const double elevation = 7.0;
const BottomNavigationBarLandscapeLayout landscapeLayout = BottomNavigationBarLandscapeLayout.spread;
await tester.pumpWidget(
MaterialApp(
......@@ -200,6 +204,7 @@ void main() {
type: BottomNavigationBarType.shifting,
selectedLabelStyle: themeSelectedTextStyle,
unselectedLabelStyle: themeUnselectedTextStyle,
landscapeLayout: themeLandscapeLayout,
),
),
home: Scaffold(
......@@ -215,6 +220,7 @@ void main() {
type: BottomNavigationBarType.fixed,
selectedLabelStyle: selectedTextStyle,
unselectedLabelStyle: unselectedTextStyle,
landscapeLayout: landscapeLayout,
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.ac_unit),
......
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