Commit a3183a4a authored by Hans Muller's avatar Hans Muller Committed by GitHub

BottomNavigationBar accepts widget icons (#7161)

parent c0af0d6a
......@@ -6,7 +6,7 @@ import 'package:flutter/material.dart';
class NavigationIconView {
NavigationIconView({
Icon icon,
Widget icon,
Widget title,
Color color,
TickerProvider vsync,
......@@ -27,7 +27,7 @@ class NavigationIconView {
);
}
final Icon _icon;
final Widget _icon;
final Color _color;
final DestinationLabel destinationLabel;
final AnimationController controller;
......@@ -51,7 +51,28 @@ class NavigationIconView {
begin: const FractionalOffset(0.0, 0.02), // Small offset from the top.
end: FractionalOffset.topLeft,
).animate(_animation),
child: new Icon(_icon.icon, color: iconColor, size: 120.0),
child: new IconTheme(
data: new IconThemeData(
color: iconColor,
size: 120.0,
),
child: _icon,
),
),
);
}
}
class CustomIcon extends StatelessWidget {
@override
Widget build(BuildContext context) {
final IconThemeData iconTheme = IconTheme.of(context).fallback();
return new Container(
margin: const EdgeInsets.all(4.0),
width: iconTheme.size - 8.0,
height: iconTheme.size - 8.0,
decoration: new BoxDecoration(
backgroundColor: iconTheme.color,
),
);
}
......@@ -80,6 +101,12 @@ class _BottomNavigationDemoState extends State<BottomNavigationDemo>
color: Colors.deepPurple[500],
vsync: this,
),
new NavigationIconView(
icon: new CustomIcon(),
title: new Text('Box'),
color: Colors.deepOrange[500],
vsync: this,
),
new NavigationIconView(
icon: new Icon(Icons.cloud),
title: new Text('Cloud'),
......
......@@ -11,7 +11,6 @@ import 'package:vector_math/vector_math_64.dart' show Vector3;
import 'colors.dart';
import 'constants.dart';
import 'icon.dart';
import 'icon_theme.dart';
import 'icon_theme_data.dart';
import 'ink_well.dart';
......@@ -59,7 +58,11 @@ class DestinationLabel {
}
/// The icon of the label.
final Icon icon;
///
/// Typically the icon is an [Icon] or an [IconImage] widget. If another type
/// of widget is provided then it should configure itself to match the current
/// [IconTheme] size and color.
final Widget icon;
/// The title of the label.
final Widget title;
......@@ -104,15 +107,15 @@ class BottomNavigationBar extends StatefulWidget {
this.onTap,
this.currentIndex: 0,
this.type: BottomNavigationBarType.fixed,
this.fixedColor
this.fixedColor,
this.iconSize: 24.0,
}) : super(key: key) {
assert(this.labels != null);
assert(this.labels.length >= 2);
assert(0 <= currentIndex && currentIndex < this.labels.length);
assert(this.type != null);
assert(
this.type == BottomNavigationBarType.fixed || this.fixedColor == null
);
assert(labels != null);
assert(labels.length >= 2);
assert(0 <= currentIndex && currentIndex < labels.length);
assert(type != null);
assert(type == BottomNavigationBarType.fixed || fixedColor == null);
assert(iconSize != null);
}
/// The interactive labels laid out within the bottom navigation bar.
......@@ -135,6 +138,13 @@ class BottomNavigationBar extends StatefulWidget {
/// [BottomNavigationBarType.fixed].
final Color fixedColor;
/// The size of all of the [DestinationLabel] icons.
///
/// This value is used to to configure the [IconTheme] for the navigation
/// bar. When a [DestinationLabel.icon] widget is not an [Icon] the widget
/// should configure itself to match the icon theme's size and color.
final double iconSize;
@override
BottomNavigationBarState createState() => new BottomNavigationBarState();
}
......@@ -251,8 +261,8 @@ class BottomNavigationBarState extends State<BottomNavigationBar> with TickerPro
return (leftWeights + _flex(animations[index]) / 2.0) / allWeights;
}
FractionalOffset cirleOffset(int index) {
final double iconSize = config.labels[index].icon.size ?? 24.0;
FractionalOffset _circleOffset(int index) {
final double iconSize = config.iconSize;
final Tween<double> yOffsetTween = new Tween<double>(
begin: (18.0 + iconSize / 2.0) / kBottomNavigationBarHeight, // 18dp + icon center
end: (6.0 + iconSize / 2.0) / kBottomNavigationBarHeight // 6dp + icon center
......@@ -332,6 +342,7 @@ class BottomNavigationBarState extends State<BottomNavigationBar> with TickerPro
child: new IconTheme(
data: new IconThemeData(
color: colorTween.evaluate(animations[i]),
size: config.iconSize,
),
child: config.labels[i].icon,
),
......@@ -400,7 +411,8 @@ class BottomNavigationBarState extends State<BottomNavigationBar> with TickerPro
),
child: new IconTheme(
data: new IconThemeData(
color: Colors.white
color: Colors.white,
size: config.iconSize,
),
child: config.labels[i].icon,
),
......@@ -507,7 +519,7 @@ class _Circle {
CurvedAnimation animation;
FractionalOffset get offset {
return state.cirleOffset(index);
return state._circleOffset(index);
}
void dispose() {
......
......@@ -240,4 +240,40 @@ void main() {
await tester.pump(const Duration(seconds: 1));
expect(Theme.of(tester.element(find.text('Alarm'))).brightness, equals(Brightness.dark));
});
testWidgets('BottomNavigationBar iconSize test', (WidgetTester tester) async {
double builderIconSize;
await tester.pumpWidget(
new Scaffold(
bottomNavigationBar: new BottomNavigationBar(
iconSize: 12.0,
labels: <DestinationLabel>[
new DestinationLabel(
title: new Text('A'),
icon: new Icon(Icons.ac_unit),
),
new DestinationLabel(
title: new Text('B'),
icon: new Builder(
builder: (BuildContext context) {
builderIconSize = IconTheme.of(context).fallback().size;
return new SizedBox(
width: builderIconSize,
height: builderIconSize,
);
},
),
),
],
),
),
);
RenderBox box = tester.renderObject(find.byType(Icon));
expect(box.size.width, equals(12.0));
expect(box.size.height, equals(12.0));
expect(builderIconSize, 12.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