Flutter---JiBottomBar底部导航栏实现2
2018-12-07 本文已影响0人
二全
在Flutter---底部导航栏实现1中,底部导航栏使用BottomNavigationBar实现的,可能会有很多种情况,例如不想要BottomNavigationBar实现的效果,只想简单的变换即可,这时候就需要自定义了
先看效果
custome.gif
该效果使用Scaffold = PageView+JiBottomBar(自定义)
JiBottomBar代码:
import 'package:flutter/material.dart';
class JiBottomBar extends StatefulWidget {
final List<JiBottomBarItem> items;
final int currentIndex;
final Color backgroundColor;
final Color textFocusColor;
final ValueChanged<int> onTap;
JiBottomBar({
@required this.items,
this.currentIndex = 0,
this.backgroundColor,
this.textFocusColor,
this.onTap,
});
@override
_JiBottomBarState createState() {
return new _JiBottomBarState();
}
}
class _JiBottomBarState extends State<JiBottomBar>{
@override
Widget build(BuildContext context) {
final List<Widget> children = <Widget>[];
for (int i = 0; i < widget.items.length; i += 1) {
children.add(_createItem(i));
}
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: children,
);
}
Widget _createItem(int i) {
JiBottomBarItem item = widget.items[i];
bool selected = i == widget.currentIndex;
return Expanded(
flex: 1,
child: Container(
color: widget.backgroundColor,
padding: EdgeInsets.only(top: 4, bottom: 4),
child: InkResponse(
onTap: (){
if(widget.onTap != null){
widget.onTap(i);
}
},
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
selected ? item.activeIcon : item.icon,
DefaultTextStyle.merge(
style: TextStyle(
fontSize: 10,
// ignore: ambiguous_import
color: selected ? widget.textFocusColor : Colors.black38,
),
child: item.title),
],
),
),
));
}
}
class JiBottomBarItem {
final Widget icon;
final Widget activeIcon;
final Widget title;
JiBottomBarItem({@required this.icon, this.title, this.activeIcon})
: assert(icon != null);
}
关键点:
1._createItem方法是创建每一个tab,用Expanded包裹,为了填充平分布局
2.内部使用了InkResponse,为了实现onTap点击事件,如果想要点击效果等,都可以使用该InkResponse实现
3.DefaultTextStyle.merge,之所以使用这个,是因为JiBottomBarItem中的title是一个widget,这时候想要实现选中高亮颜色,就需要使用该控件,并且在TextStyle中定义颜色即可,但是如果传入title的widget已经设置了颜色,或者字体大小,这里就不生效了
具体效果代码:
import 'package:flutter/material.dart';
import 'package:flutter_app/indicator/indicator.dart';
import 'home_page.dart';
import 'find_page.dart';
import 'msg_page.dart';
import 'my_page.dart';
class JiContainerPage extends StatefulWidget {
@override
_JiContainerPageState createState() {
return new _JiContainerPageState();
}
}
class _JiContainerPageState extends State<JiContainerPage>
with SingleTickerProviderStateMixin {
final PageController _pageController = new PageController(initialPage: 0);
int _tabIndex = 0;
_onPageChange(int index) {
setState(() {
_tabIndex = index;
});
}
Image _getBarIcon(int index, bool isActive) {
if (index == 0) {
return _getAssetIcon(
isActive ? "images/ic_bar_home_ed.png" : "images/ic_bar_home.png");
} else if (index == 1) {
return _getAssetIcon(
isActive ? "images/ic_bar_find_ed.png" : "images/ic_bar_find.png");
} else if (index == 2) {
return _getAssetIcon(isActive
? "images/ic_bar_notify_ed.png"
: "images/ic_bar_notify.png");
} else {
return _getAssetIcon(
isActive ? "images/ic_bar_me_ed.png" : "images/ic_bar_me.png");
}
}
Image _getAssetIcon(String path) {
return Image.asset(path, width: 24.0, height: 24.0);
}
Text _getBarText(int index) {
if (index == 0) {
return Text("首页", style: TextStyle(fontSize: 10));
} else if (index == 1) {
return Text("发现", style: TextStyle(fontSize: 10));
} else if (index == 2) {
return Text("消息", style: TextStyle(fontSize: 10));
} else {
return Text("我的", style: TextStyle(fontSize: 10));
}
}
@override
Widget build(BuildContext context) {
return new MaterialApp(
home: new Scaffold(
body: PageView.builder(
onPageChanged: _onPageChange,
controller: _pageController,
itemBuilder: (BuildContext context, int index) {
if (index == 0) {
return new JiHomePage("0000");
} else if (index == 1) {
return new JiFindPage("1111");
} else if (index == 2) {
return new JiMsgPage("2222");
} else if (index == 3) {
return new JiMyPage("3333");
}
},
itemCount: 4,
),
bottomNavigationBar: JiBottomBar(
backgroundColor: Color(0xffEEEFF2),
currentIndex: _tabIndex,
textFocusColor: Colors.deepOrange,
onTap: (index){
_pageController.jumpToPage(index);
// _pageController.animateToPage(index, duration: Duration(milliseconds: 100), curve: Curves.ease);
_onPageChange(index);
},
items: <JiBottomBarItem>[
JiBottomBarItem(
icon: _getBarIcon(0, false),
title: _getBarText(0),
activeIcon: _getBarIcon(0, true)),
JiBottomBarItem(
icon: _getBarIcon(1, false),
title: _getBarText(1),
activeIcon: _getBarIcon(1, true)),
JiBottomBarItem(
icon: _getBarIcon(2, false),
title: _getBarText(2),
activeIcon: _getBarIcon(2, true)),
JiBottomBarItem(
icon: _getBarIcon(3, false),
title: _getBarText(3),
activeIcon: _getBarIcon(3, true)),
])),
);
}
}