Unverified Commit d803f02d authored by Jonah Williams's avatar Jonah Williams Committed by GitHub

Add activeIcon property to BottomNavigationBarItem (#18125)

parent 0891a113
......@@ -7,6 +7,7 @@ import 'package:flutter/material.dart';
class NavigationIconView {
NavigationIconView({
Widget icon,
Widget activeIcon,
String title,
Color color,
TickerProvider vsync,
......@@ -15,6 +16,7 @@ class NavigationIconView {
_title = title,
item = new BottomNavigationBarItem(
icon: icon,
activeIcon: activeIcon,
title: new Text(title),
backgroundColor: color,
),
......@@ -81,6 +83,21 @@ class CustomIcon extends StatelessWidget {
}
}
class CustomInactiveIcon extends StatelessWidget {
@override
Widget build(BuildContext context) {
final IconThemeData iconTheme = IconTheme.of(context);
return new Container(
margin: const EdgeInsets.all(4.0),
width: iconTheme.size - 8.0,
height: iconTheme.size - 8.0,
decoration: new BoxDecoration(
border: new Border.all(color: iconTheme.color, width: 2.0),
)
);
}
}
class BottomNavigationDemo extends StatefulWidget {
static const String routeName = '/material/bottom_navigation';
......@@ -105,19 +122,22 @@ class _BottomNavigationDemoState extends State<BottomNavigationDemo>
vsync: this,
),
new NavigationIconView(
icon: new CustomIcon(),
activeIcon: new CustomIcon(),
icon: new CustomInactiveIcon(),
title: 'Box',
color: Colors.deepOrange,
vsync: this,
),
new NavigationIconView(
icon: const Icon(Icons.cloud),
activeIcon: const Icon(Icons.cloud),
icon: const Icon(Icons.cloud_queue),
title: 'Cloud',
color: Colors.teal,
vsync: this,
),
new NavigationIconView(
icon: const Icon(Icons.favorite),
activeIcon: const Icon(Icons.favorite),
icon: const Icon(Icons.favorite_border),
title: 'Favorites',
color: Colors.indigo,
vsync: this,
......
......@@ -189,7 +189,7 @@ class _BottomNavigationTile extends StatelessWidget {
color: iconColor,
size: iconSize,
),
child: item.icon,
child: selected ? item.activeIcon : item.icon,
),
),
);
......
......@@ -25,8 +25,10 @@ class BottomNavigationBarItem {
const BottomNavigationBarItem({
@required this.icon,
@required this.title,
Widget activeIcon,
this.backgroundColor,
}) : assert(icon != null),
}) : this.activeIcon = activeIcon ?? icon,
assert(icon != null),
assert(title != null);
/// The icon of the item.
......@@ -34,8 +36,31 @@ class BottomNavigationBarItem {
/// Typically the icon is an [Icon] or an [ImageIcon] widget. If another type
/// of widget is provided then it should configure itself to match the current
/// [IconTheme] size and color.
///
/// If [activeIcon] is provided, this will only be displayed when the item is
/// not selected.
///
/// To make the bottom navigation bar more accessible, consider choosing an
/// icon with a stroked and filled version, such as [Icons.cloud] and
/// [Icons.cloud_queue]. [icon] should be set to the stroked version and
/// [activeIcon] to the filled version.
///
/// If a particular icon doesn't have a stroked or filled version, then don't
/// pair unrelated icons. Instead, make sure to use a
/// [BottomNavigationBarType.shifting].
final Widget icon;
/// An alternative icon displayed when this bottom navigation item is
/// selected.
///
/// If this icon is not provided, the bottom navigation bar will display
/// [icon] in either state.
///
/// See also:
///
/// * [BottomNavigationBarItem.icon], for a description of how to pair icons.
final Widget activeIcon;
/// The title of the item.
final Widget title;
......
......@@ -486,6 +486,59 @@ void main() {
expect(box, paints..circle(x: 600.0)..circle(x: 200.0)..circle(x: 600.0));
});
testWidgets('BottomNavigationBar inactiveIcon shown', (WidgetTester tester) async {
const Key filled = const Key('filled');
const Key stroked = const Key('stroked');
int selectedItem = 0;
await tester.pumpWidget(
boilerplate(
textDirection: TextDirection.ltr,
bottomNavigationBar: new BottomNavigationBar(
currentIndex: selectedItem,
items: const <BottomNavigationBarItem>[
const BottomNavigationBarItem(
activeIcon: const Icon(Icons.favorite, key: filled),
icon: const Icon(Icons.favorite_border, key: stroked),
title: const Text('Favorite'),
),
const BottomNavigationBarItem(
icon: const Icon(Icons.access_alarm),
title: const Text('Alarm'),
),
],
),
),
);
expect(find.byKey(filled), findsOneWidget);
expect(find.byKey(stroked), findsNothing);
selectedItem = 1;
await tester.pumpWidget(
boilerplate(
textDirection: TextDirection.ltr,
bottomNavigationBar: new BottomNavigationBar(
currentIndex: selectedItem,
items: const <BottomNavigationBarItem>[
const BottomNavigationBarItem(
activeIcon: const Icon(Icons.favorite, key: filled),
icon: const Icon(Icons.favorite_border, key: stroked),
title: const Text('Favorite'),
),
const BottomNavigationBarItem(
icon: const Icon(Icons.access_alarm),
title: const Text('Alarm'),
),
],
),
),
);
expect(find.byKey(filled), findsNothing);
expect(find.byKey(stroked), findsOneWidget);
});
testWidgets('BottomNavigationBar semantics', (WidgetTester tester) async {
final SemanticsTester semantics = new SemanticsTester(tester);
......
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