Unverified Commit 70aa1227 authored by MH Johnson's avatar MH Johnson Committed by GitHub

[Material] Fix BottomNavTheme.showSelectedLabels bug (#67342)

parent 193fe3e9
...@@ -140,7 +140,7 @@ class BottomNavigationBar extends StatefulWidget { ...@@ -140,7 +140,7 @@ class BottomNavigationBar extends StatefulWidget {
/// Creates a bottom navigation bar which is typically used as a /// Creates a bottom navigation bar which is typically used as a
/// [Scaffold]'s [Scaffold.bottomNavigationBar] argument. /// [Scaffold]'s [Scaffold.bottomNavigationBar] argument.
/// ///
/// The length of [items] must be at least two and each item's icon and title /// The length of [items] must be at least two and each item's icon and label
/// must not be null. /// must not be null.
/// ///
/// If [type] is null then [BottomNavigationBarType.fixed] is used when there /// If [type] is null then [BottomNavigationBarType.fixed] is used when there
...@@ -164,10 +164,14 @@ class BottomNavigationBar extends StatefulWidget { ...@@ -164,10 +164,14 @@ class BottomNavigationBar extends StatefulWidget {
/// former is preferred, [fixedColor] only exists for the sake of /// former is preferred, [fixedColor] only exists for the sake of
/// backwards compatibility. /// backwards compatibility.
/// ///
/// The [showSelectedLabels] argument must be non-null. /// If [showSelectedLabels] is `null`, [BottomNavigationBarThemeData.showSelectedLabels]
/// is used. If [BottomNavigationBarThemeData.showSelectedLabels] is null,
/// then [showSelectedLabels] defaults to `true`.
/// ///
/// The [showUnselectedLabels] argument defaults to `true` if [type] is /// If [showUnselectedLabels] is `null`, [BottomNavigationBarThemeData.showUnselectedLabels]
/// [BottomNavigationBarType.fixed] and `false` if [type] is /// is used. If [BottomNavigationBarThemeData.showSelectedLabels] is null,
/// then [showUnselectedLabels] defaults to `true` when [type] is
/// [BottomNavigationBarType.fixed] and `false` when [type] is
/// [BottomNavigationBarType.shifting]. /// [BottomNavigationBarType.shifting].
BottomNavigationBar({ BottomNavigationBar({
Key? key, Key? key,
...@@ -187,7 +191,7 @@ class BottomNavigationBar extends StatefulWidget { ...@@ -187,7 +191,7 @@ class BottomNavigationBar extends StatefulWidget {
this.unselectedFontSize = 12.0, this.unselectedFontSize = 12.0,
this.selectedLabelStyle, this.selectedLabelStyle,
this.unselectedLabelStyle, this.unselectedLabelStyle,
this.showSelectedLabels = true, this.showSelectedLabels,
this.showUnselectedLabels, this.showUnselectedLabels,
this.mouseCursor, this.mouseCursor,
}) : assert(items != null), }) : assert(items != null),
...@@ -206,7 +210,6 @@ class BottomNavigationBar extends StatefulWidget { ...@@ -206,7 +210,6 @@ class BottomNavigationBar extends StatefulWidget {
), ),
assert(selectedFontSize != null && selectedFontSize >= 0.0), assert(selectedFontSize != null && selectedFontSize >= 0.0),
assert(unselectedFontSize != null && unselectedFontSize >= 0.0), assert(unselectedFontSize != null && unselectedFontSize >= 0.0),
assert(showSelectedLabels != null),
selectedItemColor = selectedItemColor ?? fixedColor, selectedItemColor = selectedItemColor ?? fixedColor,
super(key: key); super(key: key);
...@@ -286,7 +289,7 @@ class BottomNavigationBar extends StatefulWidget { ...@@ -286,7 +289,7 @@ class BottomNavigationBar extends StatefulWidget {
/// ///
/// It this field is provided, it must contain non-null [IconThemeData.size] /// It this field is provided, it must contain non-null [IconThemeData.size]
/// and [IconThemeData.color] properties. Also, if this field is supplied, /// and [IconThemeData.color] properties. Also, if this field is supplied,
/// [unselectedIconTheme] must be provided. /// [selectedIconTheme] must be provided.
final IconThemeData? unselectedIconTheme; final IconThemeData? unselectedIconTheme;
/// The [TextStyle] of the [BottomNavigationBarItem] labels when they are /// The [TextStyle] of the [BottomNavigationBarItem] labels when they are
...@@ -318,7 +321,7 @@ class BottomNavigationBar extends StatefulWidget { ...@@ -318,7 +321,7 @@ class BottomNavigationBar extends StatefulWidget {
final bool? showUnselectedLabels; final bool? showUnselectedLabels;
/// Whether the labels are shown for the selected [BottomNavigationBarItem]. /// Whether the labels are shown for the selected [BottomNavigationBarItem].
final bool showSelectedLabels; final bool? showSelectedLabels;
/// The cursor for a mouse pointer when it enters or is hovering over the /// The cursor for a mouse pointer when it enters or is hovering over the
/// tiles. /// tiles.
...@@ -346,8 +349,8 @@ class _BottomNavigationTile extends StatelessWidget { ...@@ -346,8 +349,8 @@ class _BottomNavigationTile extends StatelessWidget {
required this.unselectedLabelStyle, required this.unselectedLabelStyle,
required this.selectedIconTheme, required this.selectedIconTheme,
required this.unselectedIconTheme, required this.unselectedIconTheme,
this.showSelectedLabels, required this.showSelectedLabels,
this.showUnselectedLabels, required this.showUnselectedLabels,
this.indexLabel, this.indexLabel,
required this.mouseCursor, required this.mouseCursor,
}) : assert(type != null), }) : assert(type != null),
...@@ -371,8 +374,8 @@ class _BottomNavigationTile extends StatelessWidget { ...@@ -371,8 +374,8 @@ class _BottomNavigationTile extends StatelessWidget {
final TextStyle selectedLabelStyle; final TextStyle selectedLabelStyle;
final TextStyle unselectedLabelStyle; final TextStyle unselectedLabelStyle;
final String? indexLabel; final String? indexLabel;
final bool? showSelectedLabels; final bool showSelectedLabels;
final bool? showUnselectedLabels; final bool showUnselectedLabels;
final MouseCursor mouseCursor; final MouseCursor mouseCursor;
@override @override
...@@ -383,16 +386,10 @@ class _BottomNavigationTile extends StatelessWidget { ...@@ -383,16 +386,10 @@ class _BottomNavigationTile extends StatelessWidget {
// (which is an integer) by a large number. // (which is an integer) by a large number.
final int size; final int size;
final BottomNavigationBarThemeData bottomTheme = BottomNavigationBarTheme.of(context);
final double selectedFontSize = selectedLabelStyle.fontSize!; final double selectedFontSize = selectedLabelStyle.fontSize!;
final double selectedIconSize = selectedIconTheme?.size final double selectedIconSize = selectedIconTheme?.size ?? iconSize;
?? bottomTheme.selectedIconTheme?.size final double unselectedIconSize = unselectedIconTheme?.size ?? iconSize;
?? iconSize;
final double unselectedIconSize = unselectedIconTheme?.size
?? bottomTheme.unselectedIconTheme?.size
?? iconSize;
// The amount that the selected icon is bigger than the unselected icons, // The amount that the selected icon is bigger than the unselected icons,
// (or zero if the selected icon is not bigger than the unselected icons). // (or zero if the selected icon is not bigger than the unselected icons).
...@@ -418,9 +415,9 @@ class _BottomNavigationTile extends StatelessWidget { ...@@ -418,9 +415,9 @@ class _BottomNavigationTile extends StatelessWidget {
// | text // | text
// | <-- Padding equal to 1/2 text height + 1/2 unselectedIconDiff. // | <-- Padding equal to 1/2 text height + 1/2 unselectedIconDiff.
// ======= // =======
final double bottomPadding; double bottomPadding;
final double topPadding; double topPadding;
if (showSelectedLabels! && !showUnselectedLabels!) { if (showSelectedLabels && !showUnselectedLabels) {
bottomPadding = Tween<double>( bottomPadding = Tween<double>(
begin: selectedIconDiff / 2.0, begin: selectedIconDiff / 2.0,
end: selectedFontSize / 2.0 - unselectedIconDiff / 2.0, end: selectedFontSize / 2.0 - unselectedIconDiff / 2.0,
...@@ -429,7 +426,7 @@ class _BottomNavigationTile extends StatelessWidget { ...@@ -429,7 +426,7 @@ class _BottomNavigationTile extends StatelessWidget {
begin: selectedFontSize + selectedIconDiff / 2.0, begin: selectedFontSize + selectedIconDiff / 2.0,
end: selectedFontSize / 2.0 - unselectedIconDiff / 2.0, end: selectedFontSize / 2.0 - unselectedIconDiff / 2.0,
).evaluate(animation); ).evaluate(animation);
} else if (!showSelectedLabels! && !showUnselectedLabels!) { } else if (!showSelectedLabels && !showUnselectedLabels) {
bottomPadding = Tween<double>( bottomPadding = Tween<double>(
begin: selectedIconDiff / 2.0, begin: selectedIconDiff / 2.0,
end: unselectedIconDiff / 2.0, end: unselectedIconDiff / 2.0,
...@@ -474,8 +471,8 @@ class _BottomNavigationTile extends StatelessWidget { ...@@ -474,8 +471,8 @@ class _BottomNavigationTile extends StatelessWidget {
iconSize: iconSize, iconSize: iconSize,
selected: selected, selected: selected,
item: item, item: item,
selectedIconTheme: selectedIconTheme ?? bottomTheme.selectedIconTheme, selectedIconTheme: selectedIconTheme,
unselectedIconTheme: unselectedIconTheme ?? bottomTheme.unselectedIconTheme, unselectedIconTheme: unselectedIconTheme,
), ),
_Label( _Label(
colorTween: colorTween!, colorTween: colorTween!,
...@@ -483,8 +480,8 @@ class _BottomNavigationTile extends StatelessWidget { ...@@ -483,8 +480,8 @@ class _BottomNavigationTile extends StatelessWidget {
item: item, item: item,
selectedLabelStyle: selectedLabelStyle, selectedLabelStyle: selectedLabelStyle,
unselectedLabelStyle: unselectedLabelStyle, unselectedLabelStyle: unselectedLabelStyle,
showSelectedLabels: showSelectedLabels ?? bottomTheme.showUnselectedLabels!, showSelectedLabels: showSelectedLabels,
showUnselectedLabels: showUnselectedLabels ?? bottomTheme.showUnselectedLabels!, showUnselectedLabels: showUnselectedLabels,
), ),
], ],
), ),
...@@ -894,7 +891,7 @@ class _BottomNavigationBarState extends State<BottomNavigationBar> with TickerPr ...@@ -894,7 +891,7 @@ class _BottomNavigationBarState extends State<BottomNavigationBar> with TickerPr
colorTween: colorTween, colorTween: colorTween,
flex: _evaluateFlex(_animations[i]), flex: _evaluateFlex(_animations[i]),
selected: i == widget.currentIndex, selected: i == widget.currentIndex,
showSelectedLabels: widget.showSelectedLabels, showSelectedLabels: widget.showSelectedLabels ?? bottomTheme.showSelectedLabels ?? true,
showUnselectedLabels: widget.showUnselectedLabels ?? bottomTheme.showUnselectedLabels ?? _defaultShowUnselected, showUnselectedLabels: widget.showUnselectedLabels ?? bottomTheme.showUnselectedLabels ?? _defaultShowUnselected,
indexLabel: localizations.tabLabel(tabIndex: i + 1, tabCount: widget.items.length), indexLabel: localizations.tabLabel(tabIndex: i + 1, tabCount: widget.items.length),
mouseCursor: effectiveMouseCursor, mouseCursor: effectiveMouseCursor,
......
...@@ -58,12 +58,20 @@ class BottomNavigationBarThemeData with Diagnosticable { ...@@ -58,12 +58,20 @@ class BottomNavigationBarThemeData with Diagnosticable {
/// The size, opacity, and color of the icon in the currently selected /// The size, opacity, and color of the icon in the currently selected
/// [BottomNavigationBarItem.icon]. /// [BottomNavigationBarItem.icon].
/// ///
/// If [BottomNavigationBar.selectedIconTheme] is non-null on the widget,
/// the whole [IconThemeData] from the widget will be used over this
/// [selectedIconTheme].
///
/// See [BottomNavigationBar.selectedIconTheme]. /// See [BottomNavigationBar.selectedIconTheme].
final IconThemeData? selectedIconTheme; final IconThemeData? selectedIconTheme;
/// The size, opacity, and color of the icon in the currently unselected /// The size, opacity, and color of the icon in the currently unselected
/// [BottomNavigationBarItem.icon]s. /// [BottomNavigationBarItem.icon]s.
/// ///
/// If [BottomNavigationBar.unselectedIconTheme] is non-null on the widget,
/// the whole [IconThemeData] from the widget will be used over this
/// [unselectedIconTheme].
///
/// See [BottomNavigationBar.unselectedIconTheme]. /// See [BottomNavigationBar.unselectedIconTheme].
final IconThemeData? unselectedIconTheme; final IconThemeData? unselectedIconTheme;
......
...@@ -258,6 +258,119 @@ void main() { ...@@ -258,6 +258,119 @@ void main() {
expect(_material(tester).elevation, equals(elevation)); expect(_material(tester).elevation, equals(elevation));
expect(_material(tester).color, equals(backgroundColor)); expect(_material(tester).color, equals(backgroundColor));
}); });
testWidgets('BottomNavigationBarTheme can be used to hide all labels', (WidgetTester tester) async {
// Regression test for https://github.com/flutter/flutter/issues/66738.
await tester.pumpWidget(
MaterialApp(
theme: ThemeData(
bottomNavigationBarTheme: const BottomNavigationBarThemeData(
showSelectedLabels: false,
showUnselectedLabels: false,
),
),
home: Scaffold(
bottomNavigationBar: BottomNavigationBar(
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.ac_unit),
label: 'AC',
),
BottomNavigationBarItem(
icon: Icon(Icons.access_alarm),
label: 'Alarm',
),
],
),
),
),
);
final Finder findOpacity = find.descendant(
of: find.byType(BottomNavigationBar),
matching: find.byType(Opacity),
);
expect(findOpacity, findsNWidgets(2));
expect(tester.widget<Opacity>(findOpacity.at(0)).opacity, 0.0);
expect(tester.widget<Opacity>(findOpacity.at(1)).opacity, 0.0);
});
testWidgets('BottomNavigationBarTheme can be used to hide selected labels', (WidgetTester tester) async {
// Regression test for https://github.com/flutter/flutter/issues/66738.
await tester.pumpWidget(
MaterialApp(
theme: ThemeData(
bottomNavigationBarTheme: const BottomNavigationBarThemeData(
showSelectedLabels: false,
showUnselectedLabels: true,
),
),
home: Scaffold(
bottomNavigationBar: BottomNavigationBar(
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.ac_unit),
label: 'AC',
),
BottomNavigationBarItem(
icon: Icon(Icons.access_alarm),
label: 'Alarm',
),
],
),
),
),
);
final Finder findFadeTransition = find.descendant(
of: find.byType(BottomNavigationBar),
matching: find.byType(FadeTransition),
);
expect(findFadeTransition, findsNWidgets(2));
expect(tester.widget<FadeTransition>(findFadeTransition.at(0)).opacity.value, 0.0);
expect(tester.widget<FadeTransition>(findFadeTransition.at(1)).opacity.value, 1.0);
});
testWidgets('BottomNavigationBarTheme can be used to hide unselected labels', (WidgetTester tester) async {
await tester.pumpWidget(
MaterialApp(
theme: ThemeData(
bottomNavigationBarTheme: const BottomNavigationBarThemeData(
showSelectedLabels: true,
showUnselectedLabels: false,
),
),
home: Scaffold(
bottomNavigationBar: BottomNavigationBar(
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.ac_unit),
label: 'AC',
),
BottomNavigationBarItem(
icon: Icon(Icons.access_alarm),
label: 'Alarm',
),
],
),
),
),
);
final Finder findFadeTransition = find.descendant(
of: find.byType(BottomNavigationBar),
matching: find.byType(FadeTransition),
);
expect(findFadeTransition, findsNWidgets(2));
expect(tester.widget<FadeTransition>(findFadeTransition.at(0)).opacity.value, 1.0);
expect(tester.widget<FadeTransition>(findFadeTransition.at(1)).opacity.value, 0.0);
});
} }
TextStyle _iconStyle(WidgetTester tester, IconData icon) { TextStyle _iconStyle(WidgetTester tester, IconData icon) {
......
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