Commit ef68f2f0 authored by Dragoș Tiselice's avatar Dragoș Tiselice Committed by GitHub

Added BottomNavigationBar demo. (#6003)

Added a demo of BottomNavigation to the Gallery.
parent 4c1e4a24
......@@ -3,6 +3,7 @@
// found in the LICENSE file.
export 'animation_demo.dart';
export 'bottom_navigation_demo.dart';
export 'buttons_demo.dart';
export 'contacts_demo.dart';
export 'cards_demo.dart';
......
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter/material.dart';
class NavigationIconView {
NavigationIconView({
Icon icon,
Widget title,
Color color
}) : _icon = icon,
_color = color,
destinationLabel = new DestinationLabel(
icon: icon,
title: title,
backgroundColor: color
),
controller = new AnimationController(
duration: kThemeAnimationDuration
) {
_animation = new CurvedAnimation(
parent: controller,
curve: new Interval(0.5, 1.0, curve: Curves.fastOutSlowIn)
);
}
final Icon _icon;
final Color _color;
final DestinationLabel destinationLabel;
final AnimationController controller;
CurvedAnimation _animation;
FadeTransition transition(BottomNavigationBarType type, BuildContext context) {
Color iconColor;
if (type == BottomNavigationBarType.shifting) {
iconColor = _color;
} else {
final ThemeData themeData = Theme.of(context);
iconColor = themeData.brightness == Brightness.light ?
themeData.primaryColor : themeData.accentColor;
}
return new FadeTransition(
opacity: _animation,
child: new SlideTransition(
position: new Tween<FractionalOffset>(
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)
)
);
}
}
class BottomNavigationDemo extends StatefulWidget {
static const String routeName = '/bottom_navigation';
@override
_BottomNavigationDemoState createState() => new _BottomNavigationDemoState();
}
class _BottomNavigationDemoState extends State<BottomNavigationDemo> {
int _currentIndex = 0;
BottomNavigationBarType _type = BottomNavigationBarType.shifting;
List<NavigationIconView> _navigationViews;
@override
void initState() {
super.initState();
_navigationViews = <NavigationIconView>[
new NavigationIconView(
icon: new Icon(Icons.access_alarm),
title: new Text('Alarm'),
color: Colors.deepPurple[500]
),
new NavigationIconView(
icon: new Icon(Icons.cloud),
title: new Text('Cloud'),
color: Colors.teal[500]
),
new NavigationIconView(
icon: new Icon(Icons.favorite),
title: new Text('Favorites'),
color: Colors.indigo[500]
),
new NavigationIconView(
icon: new Icon(Icons.event_available),
title: new Text('Event'),
color: Colors.pink[500]
)
];
for (NavigationIconView view in _navigationViews)
view.controller.addListener(_rebuild);
_navigationViews[_currentIndex].controller.value = 1.0;
}
@override
void dispose() {
for (NavigationIconView view in _navigationViews)
view.controller.dispose();
super.dispose();
}
void _rebuild() {
setState(() {
// Rebuild in order to animate views.
});
}
Widget _buildBody() {
final List<FadeTransition> transitions = <FadeTransition>[];
for (NavigationIconView view in _navigationViews)
transitions.add(view.transition(_type, context));
// We want to have the newly animating (fading in) views on top.
transitions.sort((FadeTransition a, FadeTransition b) {
double aValue = a.animation.value;
double bValue = b.animation.value;
return aValue.compareTo(bValue);
});
return new Stack(
children: transitions
);
}
@override
Widget build(BuildContext context) {
BottomNavigationBar botNavBar = new BottomNavigationBar(
labels: _navigationViews.map(
(NavigationIconView navigationView) => navigationView.destinationLabel
).toList(),
currentIndex: _currentIndex,
type: _type,
onTap: (int index) {
setState(() {
_navigationViews[_currentIndex].controller.reverse();
_currentIndex = index;
_navigationViews[_currentIndex].controller.forward();
});
}
);
return new Scaffold(
appBar: new AppBar(
title: new Text('Bottom navigation'),
actions: <Widget>[
new PopupMenuButton<BottomNavigationBarType>(
onSelected: (BottomNavigationBarType value) {
setState(() {
_type = value;
});
},
itemBuilder: (BuildContext context) => <PopupMenuItem<BottomNavigationBarType>>[
new PopupMenuItem<BottomNavigationBarType>(
value: BottomNavigationBarType.fixed,
child: new Text('Fixed')
),
new PopupMenuItem<BottomNavigationBarType>(
value: BottomNavigationBarType.shifting,
child: new Text('Shifting')
)
]
)
]
),
body: _buildBody(),
bottomNavigationBar: botNavBar
);
}
}
......@@ -66,6 +66,12 @@ final List<GalleryItem> kAllGalleryItems = <GalleryItem>[
buildRoute: (BuildContext context) => new ContactsDemo()
),
// Components
new GalleryItem(
title: 'Bottom navigation',
subtitle: 'Bottom navigation with cross-fading views',
routeName: BottomNavigationDemo.routeName,
buildRoute: (BuildContext context) => new BottomNavigationDemo()
),
new GalleryItem(
title: 'Buttons',
subtitle: 'All kinds: flat, raised, dropdown, icon, etc',
......
......@@ -27,6 +27,7 @@ final List<String> demoTitles = <String>[
'Shrine',
'Contact profile',
// Components
'Bottom navigation',
'Buttons',
'Cards',
'Chips',
......
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