一、Flutter实现底部导航栏
在手机端App主界面中,我们经常看到下面有多个按钮Tab,点击下面的Tab,切换上面的页面。类似与如下效果
在实现Flutter实现底部导航栏的时候,我们先学习连个widget.
1、BottomNavigationBar
BottomNavigationBar({
Key key,
@required this.items, //子选项
this.onTap, //点击事件
this.currentIndex = 0,//选中第几个
BottomNavigationBarType type, //底部导航栏样式
this.fixedColor,//文字颜色
this.iconSize = 24.0,//icon图片大小
Color selectedItemColor, //选中item的颜色
this.unselectedItemColor,//未选中的item颜色
this.selectedIconTheme = const IconThemeData(), //选中图标样式
this.unselectedIconTheme = const IconThemeData(),//未选中图标样式
this.selectedFontSize = 14.0, //选中字体大小
this.unselectedFontSize = 12.0,//为选中字体大小
this.selectedLabelStyle,//选中标签的样式
this.unselectedLabelStyle,//未选中标签样式
this.showSelectedLabels = true,//是否显示选中对象的标签
bool showUnselectedLabels,//是否显示未选中对象的标签
})
const BottomNavigationBarItem({
@required this.icon,//未选中图标
this.title,//文字
Widget activeIcon,//选中图标
this.backgroundColor,// 测试发现type设置为shifting时,backgroundColor才有效
})
BottomNavigationBar的使用用方法如下:
bottomNavigationBar: new BottomNavigationBar(
currentIndex: _currentIndex,
selectedLabelStyle: TextStyle(color: selectColor,fontSize: 14),
unselectedLabelStyle: TextStyle(color: unSelectColor,fontSize: 12),
unselectedIconTheme: IconThemeData(color: unSelectColor),
selectedIconTheme: IconThemeData(color: selectColor),
onTap: (index) {
mPageController.jumpToPage(index);
setState(() {
_currentIndex = index;
});
},
items: [
createBottomTab(Icons.home, mTabs[0]),
createBottomTab(Icons.local_hospital,mTabs[1]),
createBottomTab(Icons.account_balance, mTabs[2]),
],
),
因为item中标签除图标和文本之外基本不一致,所以我们创建一个方法,嗲用即可:
createBottomTab1(IconData icon, String title) {
return new BottomNavigationBarItem(
icon: Icon(
icon,
),
title: new Text(
title,
));
}
2、PageView
PageView({
Key key,
this.scrollDirection = Axis.horizontal, //滑动在轴上的方向
this.reverse = false, //在轴方向上方向是否颠倒
PageController controller, //Page控制器
this.physics, //页面响应用户交互方式
this.pageSnapping = true,//设置为false可禁用页面捕捉,这对于自定义滚动行为很有用。
this.onPageChanged,//页面发生改变时出发
List<Widget> children = const <Widget>[],//页面widget
this.dragStartBehavior = DragStartBehavior.start,//设置拖拽方式
})
PageController({
this.initialPage = 0, //初始显示页面
this.keepPage = true, //页面加载后是否保留页面
this.viewportFraction = 1.0,//页面占据空间的大小
})
PageView使用如下
PageView(
controller: mPageController,
children: widget.mViews,
onPageChanged: (index){
mTabController.animateTo(index);
setState(() {
_currentIndex = index;
});
},
),
完整代码如下:
class MainApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
// TODO: implement build
return new MaterialApp(
home: new Scaffold(
body: new MainWidget(),
),
);
}
}
class MainWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
// TODO: implement build
List<Widget> mViews = [
new Home(),
new Work(),
new Mine(),
];
List<String> mTabs = ["首页", "办事", "我的"];
return new WillPopScope(child: new TabNavigator('鸽子飞飞飞', mTabs, mViews,Colors.red,Colors.grey), onWillPop: null);
}
}
class TabNavigator extends StatefulWidget {
/*定义标题*/
final String title;
/*底部标题文本*/
final List<String> mTabs;
/*根视图,相当于Fragment视图*/
final List<Widget> mViews;
/*设置选中空间的颜色值*/
final Color selectColor;
final Color unSelectColor;
TabNavigator(this.title, this.mTabs, this.mViews, this.selectColor,
this.unSelectColor);
@override
State<StatefulWidget> createState() {
// TODO: implement createState
return new _TabNavigatorState(title, mTabs,selectColor, unSelectColor);
}
}
class _TabNavigatorState extends State<TabNavigator>
with SingleTickerProviderStateMixin {
final String title;
final List<String> mTabs;
final Color selectColor;
final Color unSelectColor;
_TabNavigatorState(this.title, this.mTabs,this.selectColor, this.unSelectColor);
int _currentIndex = 0;
PageController mPageController;
TabController mTabController;
@override
void initState() {
// TODO: implement initState
super.initState();
mPageController = new PageController(initialPage: 0, keepPage: true);
mTabController =
new TabController(length: widget.mViews.length, vsync: this);
}
@override
void dispose() {
// TODO: implement dispose
super.dispose();
mPageController.dispose();
mTabController.dispose();
}
@override
Widget build(BuildContext context) {
// TODO: implement build
return new Scaffold(
appBar: new AppBar(
title: new Text('$title'),
),
bottomNavigationBar: new BottomNavigationBar(
currentIndex: _currentIndex,
selectedLabelStyle: TextStyle(color: selectColor,fontSize: 14),
unselectedLabelStyle: TextStyle(color: unSelectColor,fontSize: 12),
unselectedIconTheme: IconThemeData(color: unSelectColor),
selectedIconTheme: IconThemeData(color: selectColor),
onTap: (index) {
mPageController.jumpToPage(index);
setState(() {
_currentIndex = index;
});
},
items: [
// createBottomTab(Icons.home, mTabs[0],0),
createBottomTab1(Icons.home, mTabs[0]),
//createBottomTab(Icons.local_hospital,mTabs[1],1),
createBottomTab1(Icons.local_hospital,mTabs[1]),
//createBottomTab(Icons.account_balance, mTabs[2],2),
createBottomTab1(Icons.account_balance, mTabs[2]),
],
),
body: PageView(
controller: mPageController,
children: widget.mViews,
onPageChanged: (index){
mTabController.animateTo(index);
setState(() {
_currentIndex = index;
});
},
),
);
}
createBottomTab1(IconData icon, String title) {
return new BottomNavigationBarItem(
icon: Icon(
icon,
),
title: new Text(
title,
));
}
}
运行的时候,只需要在main方法中执行runApp即可
void main() {
runApp(MainApp());
}