首页 > 建站教程 > APP开发,混合APP >  Flutter bottomNavigationBar和DefaultTabController实战正文

Flutter bottomNavigationBar和DefaultTabController实战

这是转载自简书星星编程的一篇博文,感谢分享。

本文通过一个案例,展示了Flutter通过bottomNavigationBar和DefaultTabController组件实现底部tab栏和顶部tab栏的实现:

下图是最终效果:



可以看到,顶部有搜索框和tabbar,使用了自定义AppBar配合DefaultTabController实现,底部为常见的bottomNavigationBar tab栏。

一、通过bottomNavigationBar实现底部:
    重新build方法会返回一个Scaffold组件,在这个组件下面添加底部导航属性bottomNavigationBar,onTap事件实现点击底部导航栏页面之间的切换和状态改变。因为界面有变化,所以这里使用的是动态组件StatefulWidget。
01@override
02  Widget build(BuildContext context) {
03    return Scaffold(
04      backgroundColor: Color.fromRGBO(244, 245, 245, 1.0),
05      bottomNavigationBar: BottomNavigationBar(
06        type:BottomNavigationBarType.fixed,
07        currentIndex: currentIndex,
08        items:_bottomTabs,
09        onTap: (index){
10          setState(() {
11           currentIndex = index;
12           currentPage = _tabs[currentIndex];
13          });
14        },
15       fixedColor: Colors.green,
16      ),
17      body:currentPage
18    );
19}
    _bottomTabs是定义的底部Tabbar的List<BottomNavigationBarItem>,包含了Tabbar的每个item。item有默认icon和选择的activeIcon,这里使用的都是加载的本地图片,加载本地图片需要以下配置。

    1、以当前Demo为例,建立一个assets文件夹images,下面建2.0x和3.0x两个文件夹,用来放2倍图和3倍图,另外直接在images文件夹下放一倍图。



    2、需要在pubspec.yaml文件中声明每张图片。



    3、Tabbar每个item的icon和activeIcon加载本地图。
01final List<BottomNavigationBarItem> _bottomTabs = [
02    BottomNavigationBarItem(
03      icon:Image.asset("images/ic_tab_home_normal.png",fit: BoxFit.cover,width: 40,height: 40,),
04      activeIcon:Image.asset("images/ic_tab_home_active.png",fit: BoxFit.cover,width: 40,height: 40,),
05      title:Text('首页')
06    ),
07    BottomNavigationBarItem(
08      icon:Image.asset("images/ic_tab_subject_normal.png",fit: BoxFit.cover,width: 40,height: 40,),
09      activeIcon:Image.asset("images/ic_tab_subject_active.png",fit: BoxFit.cover,width: 40,height: 40,),
10      title:Text('书影音')
11    ),
12    BottomNavigationBarItem(
13      icon:Image.asset("images/ic_tab_group_normal.png",fit: BoxFit.cover,width: 40,height: 40,),
14      activeIcon:Image.asset("images/ic_tab_group_active.png",fit: BoxFit.cover,width: 40,height: 40,),
15      title:Text('小组')
16    ),
17     BottomNavigationBarItem(
18      icon:Image.asset("images/ic_tab_shiji_normal.png",fit: BoxFit.cover,width: 40,height: 40,),
19      activeIcon:Image.asset("images/ic_tab_shiji_active.png",fit: BoxFit.cover,width: 40,height: 40,),
20      title:Text('市集')
21    ),
22     BottomNavigationBarItem(
23      icon:Image.asset("images/ic_tab_profile_normal.png",fit: BoxFit.cover,width: 40,height: 40,),
24      activeIcon: Image.asset("images/ic_tab_profile_active.png",fit: BoxFit.cover,width: 40,height: 40,),
25      title:Text('我的')
26    )
27];
    _tabs是Tabbar所有页面的集合:
1final List _tabs = [
2    TopBarPage(),
3    AudioBook(),
4    Team(),
5    Fair(),
6    Mine()
7];
    在initState初始化currentPage,显示首页:
1@override
2void initState() {
3    super.initState();
4    currentPage=_tabs[currentIndex];
5}
    切换Tabbar实现onTap刷新状态并更改currentPage渲染页面。

二、顶部Tabbar
    顶部Tabbar相对于底部Tabbar简单一些,顶部Tabbar切换时不需要手动改变状态,所以这里使用StatelessWidget。顶部Tabbar使用DefaultTabController组件,声明切换item的个数length属性,并保证与tabs和TabBarView的个数一致,否则会报错。
    AppBar组件下的Title也是一个组件,这里添加一个自定义的搜索组件SearchTextFieldWidget,这里就不过多介绍了。
01@override
02Widget build(BuildContext context) {
03    return DefaultTabController(
04      length: 6,
05      child: Scaffold(
06        appBar: AppBar(
07          title: SearchTextFieldWidget(
08              hintText: "用一部电影来形容你的2019",
09              onSubmitted: (searchContent) {
10                 
11              },
12            ),
13         backgroundColor: Colors.green,
14          bottom: TabBar(
15            indicatorColor: Colors.white,
16            tabs: <Widget>[
17              Tab(
18                text: "电影",
19              ),
20              Tab(
21                text: "电视",
22              ),
23               Tab(
24                text: "综艺",
25              ),
26               Tab(
27                text: "读书",
28              ),
29              Tab(
30                text: "音乐",
31              ),
32              Tab(
33                text: "同城",
34              )
35            ],
36          ),
37        ),
38        body: TabBarView(
39          children: <Widget>[Home(), Home(), Home(), Home(), Home(), Home()],
40        ),
41      ),
42    );
43}