之前写过的一篇文章介绍了 Flutter - 创建横跨所有页面的侧滑菜单, 这次就一起来学习一下底部导航栏。
底部导航栏在ios平台上非常常见,app store就是这样的风格。还有就是大家最常用的微信,也是底部导航的。
既然这么常见的功能,在Flutter上面也是必不可少的啦。谷歌已经做好了Widget,下面我们就来看一下如何创建一个底部导航栏。
1. 准备工作
首先创建一个空的Flutter 项目,并且按照图示结构。创建一个pages文件夹,并新建四个page文件。
这四个pages是用到导航的页面,也即是说,你点击底部的一个图标,就是自动导航到这个页面,
这四个page结构基本相同,这里只放置home的代码
import 'package:flutter/material.dart'; class Home extends StatelessWidget{
@override
Widget build(BuildContext context){
return new Center(
child: Text('Home'),
);
}
}
2. 添加引用
在main.dart顶部,添加对四个页面的引用,用相对路径或者完整的项目路径
3. 定义一个List<BottomNavigationBarItem>和一个List<Widget>
比如你底部导航栏有几个图标,那么就需要添加几个BottomNavigationBarItem。不过我好像在哪看过,不要添加过多的底部导航,最多5个。一般应该没有超过5个图标的吧。
List<Widget>存放你的页面
List<BottomNavigationBarItem>存放底部图标
final List<BottomNavigationBarItem> _list = <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.home),
title: Text('Home'),
//backgroundColor: Colors.orange
),
BottomNavigationBarItem(
icon: Icon(Icons.book),
title: Text('Book'),
//backgroundColor: Colors.orange
),
BottomNavigationBarItem(
icon: Icon(Icons.music_video),
title: Text('Music'),
//backgroundColor: Colors.orange
),
BottomNavigationBarItem(
icon: Icon(Icons.movie),
title: Text('Movie'),
//backgroundColor: Colors.orange
),
];
4. 构建底部导航,并添加点击事件
在Scaffold脚手架里面,我们添加基本的
appbar
body,这个是List<Widget>,导航页面数组
bottomNavigationBar, 设置其type、items、currentIndex,当然还有onTap事件
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Bottom Navigation'),
),
bottomNavigationBar: BottomNavigationBar(
type: BottomNavigationBarType.shifting,
onTap: onTabTapped,
currentIndex: _currentIndex,
items: _list,
),
body: _children[_currentIndex],
);
} void onTabTapped(int index) {
setState(() {
_currentIndex = index;
});
}
_currentIndex需要在前面定义一下,是点击索引,这样通过setState告诉Scaffold,你点击了哪一个,它在显示哪一个了。
onTap事件,主要用了一下setState方法。
5. 一个好玩有趣的参数
大家可能注意到了,我刚才在 BottomNavigationBar里面加了type预定义参数,值为
BottomNavigationBarType.shifting
如果不加的话,它也是默认。
但是,type也可以为
BottomNavigationBarType.fixed
当你设置为fixed模式时,这个时候酒和微信的模式一模一样了,即icon和title都是固定的。
如果时shifting模式,那么当前选择的那个图标就是图标突出的,并且其他未选择的不显示title。
可以尝试一下。
6. 完整代码
import 'package:flutter/material.dart'; import './pages/home_page.dart';
import './pages/book_page.dart';
import 'package:bottom_nav_bar_test/pages/movie_page.dart';
import 'package:bottom_nav_bar_test/pages/music_page.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Bottom Navigation',
home: Homes(),
theme: ThemeData(primaryColor: Colors.orange),
);
}
} class Homes extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return _HomesState();
}
} class _HomesState extends State<Homes> {
int _currentIndex = 0;
final List<Widget> _children = [Home(), Book(), Music(), Movie()]; final List<BottomNavigationBarItem> _list = <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.home),
title: Text('Home'),
//backgroundColor: Colors.orange
),
BottomNavigationBarItem(
icon: Icon(Icons.book),
title: Text('Book'),
//backgroundColor: Colors.orange
),
BottomNavigationBarItem(
icon: Icon(Icons.music_video),
title: Text('Music'),
//backgroundColor: Colors.orange
),
BottomNavigationBarItem(
icon: Icon(Icons.movie),
title: Text('Movie'),
//backgroundColor: Colors.orange
),
]; @override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Bottom Navigation'),
),
bottomNavigationBar: BottomNavigationBar(
type: BottomNavigationBarType.fixed,
onTap: onTabTapped,
currentIndex: _currentIndex,
items: _list,
),
body: _children[_currentIndex],
);
} void onTabTapped(int index) {
setState(() {
_currentIndex = index;
});
}
}
7. 结束啦
底部导航栏使用方法并不难,只要按照上述步骤,就可以完成一个属于自己的底部导航栏。
偷偷的告诉你,你可以在谷歌山谷搜一下微信的图标集,然后用Flutter做一个高仿微信界面,也是有可能的。
哦,还有一句,在你点击底部导航菜单的时候,图标会自动显示水波纹效果,也就是InkWell那样的效果。
Cool