底部导航栏 BottomNavigationBar
App应用中底部导航栏是超级常见的。Android中实现底部导航栏的方式有很多种,Flutter中也存在多种方式,这里介绍使用起来简单的官方系统控件BottomNavigationBar
方式,该方式只能点击切换不同界面,不支持滑动切换。
本文实现效果如图:
常用属性
- items
tab集合,item类是BottomNavigationBarItem。
BottomNavigationBarItem的常用属性:- icon
图标控件。Material Design中不能为空。 - title
标题字符串。Material Design中不能为空。 - activeIcon
激活状态下的图标控件,一般情况下不会设置该属性。
- icon
- currentIndex
items的激活状态的下标。 - onTap
items子项的点击事件,一般情况下我们调用setState方法更新currentIndex的值来刷新底部导航栏的UI。 - elevation
Z轴偏移值,默认值为8,底部与上面会有明显的立体隔层效果。如果改成0则是平面顺滑的效果。 - fixedColor、selectedItemColor
选中item的文字和图标的颜色值,默认为主题颜色。两者不能同时设置。 - unselectedItemColor
未选中的item的色值,默认淡黑色。 - backgroundColor
导航栏背景色值。 - iconSize
图标大小,默认24,一般不建议修改。 - selectedFontSize、unselectedFontSize
选中item的文字大小、未选中item的文字大小,默认分别为14、12。
简单代码:
import 'package:flutter/material.dart';
import 'package:flutter_demo/pages/PageOne.dart';
import 'package:flutter_demo/pages/PageThree.dart';
import 'package:flutter_demo/pages/PageTwo.dart';
/// create on 2019/5/21 by JasonZhang
/// desc:主界面
class MainHome extends StatelessWidget {
@override
Widget build(BuildContext context) => new MaterialApp(home: MyHomePage());
}
class MyHomePage extends StatefulWidget {
@override
State<StatefulWidget> createState() => new MyHomePageState();
}
class MyHomePageState extends State<MyHomePage>
with SingleTickerProviderStateMixin {
List<Widget> mPages = List<Widget>(); // 主界面的页面列表
int mCurrentIndex = 0; // 当前展示的界面下标
@override
void initState() {
super.initState();
mPages
..add(PageOne())
..add(PageTwo())
..add(PageThree()); // 初始化申明三个Tab页面。 .. 串起来
// mPages.add(PageOne());
// mPages.add(PageTwo());
// mPages.add(PageThree());
}
@override
Widget build(BuildContext context) {
return MaterialApp(
title: "首页主界面",
theme: ThemeData(primarySwatch: Colors.blue),
home: Scaffold(
body: mPages[mCurrentIndex], // body显示的界面
bottomNavigationBar: new BottomNavigationBar(
items: [
// 底部三个item,指定图标和文案。Icons.home等图标是系统自带提供的。
// currentIndex的item的图标和文案颜色为theme颜色,未激活状态的为默认黑色
// 也可以用activeIcon指定激活状态下的ICON图标,一般不会这样做
BottomNavigationBarItem(
icon: Icon(Icons.home),
title: Text('模板中心'),
/*activeIcon: Icon(Icons.access_alarm)*/),
BottomNavigationBarItem(
icon: Icon(Icons.list), title: Text('我的作品')),
BottomNavigationBarItem(
icon: Icon(Icons.message), title: Text('我的信息'))
],
currentIndex: mCurrentIndex, // 指定下标值等于mCurrentIndex变量
onTap: (int index) {
// 点击事件,点击下标值赋给mCurrentIndex,触发改变currentIndex值、刷新底部导航栏的样式
setState(() {
mCurrentIndex = index;
});
},
),
),
);
}
}
import 'package:flutter/material.dart';
class PageOne extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: "模板中心",
theme: ThemeData(primarySwatch: Colors.blue),
home: Scaffold(
appBar: AppBar(title: Text("模板中心")),
),
);
}
}
PageTwo、PageThree代码与PageOne几乎一样。
本文源码:TAG,下载源码需指定tag。
20190530更新
实际使用中发现,BottomNavigationBar的方式在切换Tab时,界面每次展示都是重新创建的,如果有网络请求等每次都会进行请求。网上有提供一些方法解决这个问题,个人觉得有点复杂就没尝试,而是换了一个实现方式:CupertinoTabScaffold
。使用方式类似,语法等也简单就不详细介绍了,实现效果与BottomNavigationBar的操作一致,也只能点击切换。
更改后源码:
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_demo/pages/PageOne.dart';
import 'package:flutter_demo/pages/PageThree.dart';
import 'package:flutter_demo/pages/PageTwo.dart';
/// create on 2019/5/21 by JasonZhang
/// desc:主界面
class MainHome extends StatelessWidget {
@override
Widget build(BuildContext context) => new MaterialApp(home: MyHomePage());
}
class MyHomePage extends StatefulWidget {
@override
State<StatefulWidget> createState() => new MyHomePageState();
}
class MyHomePageState extends State<MyHomePage> {
List<Widget> mPageList = new List();
@override
void initState() {
super.initState();
mPageList.add(new PageOne());
mPageList.add(new PageTwo());
mPageList.add(new PageThree());
}
@override
Widget build(BuildContext context) {
return MaterialApp(
title: "首页主界面",
theme: ThemeData(primarySwatch: Colors.blue),
home: CupertinoTabScaffold(
tabBar: CupertinoTabBar(
backgroundColor: Colors.white,
items: [
// 底部三个item,指定图标和文案。Icons.home等图标是系统自带提供的。
BottomNavigationBarItem(
icon: Icon(
Icons.home,
size: 24,
),
title: Text('模板中心'),
),
BottomNavigationBarItem(
icon: Icon(
Icons.list,
size: 24,
),
title: Text('我的作品')),
BottomNavigationBarItem(
icon: Icon(
Icons.message,
size: 24,
),
title: Text('我的信息'))
],
),
tabBuilder: (BuildContext context, int index) {
// 需要放在集合中指向每次复用对象,如果这里写new PageOne()则每次也是重新创建。
return mPageList[index];
}));
}
}
本次更新源码:TAG,下载源码需指定tag。