BottomNavigationBar是谷歌最新推出实现底部导航栏控件,属于Material Design风格。在此之前我们要是实现底部导航栏写法各有不同,比如早些时使用TabHost来实现,还有LinearLayout + TextView、RadioGroup + RadioButton、TabLayout+ViewPager等。
使用BottomNavigationBar实现底部导航栏效果只需三步骤。既然是控件,那么布局是要有的,java核心代码必不可少,使用之前我们还需添加依赖。先看例子效果图:
第一步:添加依赖
compile 'com.ashokvarma.android:bottom-navigation-bar:1.3.0'
第二步:布局文件
1.主布局 activity_main
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<!--内容区域-->
<FrameLayout
android:id="@+id/frame_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!--设置默认Fragment-->
<include layout="@layout/home_fragment"/>
</FrameLayout>
<!--BottomNavigationBar-->
<com.ashokvarma.bottomnavigation.BottomNavigationBar
android:id="@+id/bottom_navigation_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
>
</com.ashokvarma.bottomnavigation.BottomNavigationBar>
</RelativeLayout>
2.碎片布局(碎片布局有四个,这里只贴出其中之一,其他雷同
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ImageView
android:id="@+id/imageView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:src="@drawable/img_home" />
</LinearLayout>
第三部:java核心代码
1.BaseFragment(懒加载
/**
* Created by Dell on 2017/5/11.
*实现懒加载方法
*/
public class BaseFragment extends Fragment {
//Fragment的View加载完毕的标记
private boolean isViewCreated;
//Fragment对用户可见的标记
private boolean isUIVisible;
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
isViewCreated = true;
lazyLoad();
}
/**
* 重写Fragment父类生命周期方法,在onCreate之前调用该方法,
* 实现Fragment数据的缓加载.
* @param isVisibleToUser//表示该Fragment的UI对于用户是否可见
*/
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
//当setUserVisibleHint(boolean isVisibleToUser)回调为true时,
//改变isVisible标记为true,并调用lazyLoad()方法
//isVisibleToUser这个boolean值表示:该Fragment的UI 用户是否可见
if (isVisibleToUser) {
isUIVisible = true;
lazyLoad();
} else {
isUIVisible = false;
}
}
public void lazyLoad(){
//这里进行双重标记判断,是因为setUserVisibleHint会多次回调,
//并且会在onCreateView执行前回调,必须确保onCreateView加载完毕且页面可见,
//才加载数据
if (isViewCreated && isUIVisible) {
loadData();
//数据加载完毕,恢复标记,防止重复加载
isViewCreated = false;
isUIVisible = false;
}
}
public void loadData(){
}
}
2.HomeFragment(其他三个一样,只贴出一个
public class HomeFragment extends BaseFragment {
private View homeView;
private ImageView mImageView;
@Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container,
Bundle savedInstanceState) {
homeView=inflater.inflate(R.layout.home_fragment,container,false);
initView();
return homeView;
}
/**
* 初始化布局
*/
private void initView() {
mImageView= (ImageView) homeView.findViewById(R.id.imageView);
}
/**
* 加载数据方法
*/
@Override
public void loadData() {
super.loadData();
}
}
3.MainActivity
public class MainActivity extends AppCompatActivity implements
BottomNavigationBar.OnTabSelectedListener{
//定义BottomNavigationBar对象
private BottomNavigationBar mBottomNavigationBar;
private HomeFragment mHomeFragment;
private ShoppingCartFragment mShoppingCartFragment;
private MessageFragment mMessageFragment;
private MyFragment mMyFragment;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
}
private void initView() {
mBottomNavigationBar = (BottomNavigationBar) findViewById(R.id.bottom_navigation_bar);
//Background 模式
mBottomNavigationBar.setMode(BottomNavigationBar.MODE_FIXED);
//Background Style
mBottomNavigationBar.setBackgroundStyle(BottomNavigationBar.BACKGROUND_STYLE_STATIC);
//设置未点击颜色
mBottomNavigationBar.setInActiveColor(R.color.hei);
//图标和文字的颜色一致(设置点击颜色)
mBottomNavigationBar.setActiveColor(R.color.green);
//设置BottomNavigationBar的背景色
mBottomNavigationBar.setBarBackgroundColor(R.color.orange);
List<BottomNavigationItem> items = new ArrayList<>();
items.add(getItem(R.drawable.ic_home,R.string.app_home));
items.add(getItem(R.drawable.ic_cart, R.string.app_shop_car));
items.add(getItem(R.drawable.ic_mms, R.string.app_message));
items.add(getItem(R.drawable.ic_mine, R.string.app_mine));
for (BottomNavigationItem item : items) {
mBottomNavigationBar.addItem(item);
}
mBottomNavigationBar.setFirstSelectedPosition(0);
mBottomNavigationBar.initialise();
mBottomNavigationBar.setTabSelectedListener(this);
}
private BottomNavigationItem getItem(int icon, int string) {
return new BottomNavigationItem(icon, string);
}
/**
* BottomNavigationBar被选中
* @param position
*/
@Override
public void onTabSelected(int position) {
FragmentTransaction beginTransaction = getSupportFragmentManager().beginTransaction();
// 先隐藏掉所有的Fragment,以防止有多个Fragment显示在界面上的情况
hideFragments(beginTransaction);
switch (position) {
case 0:
if (mHomeFragment==null){
mHomeFragment=new HomeFragment();
beginTransaction.add(R.id.frame_layout,mHomeFragment);
}
// 如果Fragment不为空,则直接将它显示出来
if (mHomeFragment!=null){
beginTransaction.show(mHomeFragment);
}
beginTransaction.addToBackStack(null);
break;
case 1:
//显示、加载Fragment
if (mShoppingCartFragment==null){
// 如果fragment为空,则创建一个并添加到界面上
mShoppingCartFragment=new ShoppingCartFragment();
beginTransaction.add(R.id.frame_layout,mShoppingCartFragment);
}else {
// 如果Fragment不为空,则直接将它显示出来
beginTransaction.show(mShoppingCartFragment);
}
beginTransaction.addToBackStack(null);
break;
case 2:
//显示、加载Fragment
if (mMessageFragment==null){
// 如果fragment为空,则创建一个并添加到界面上
mMessageFragment=new MessageFragment();
beginTransaction.add(R.id.frame_layout,mMessageFragment);
}else {
// 如果Fragment不为空,则直接将它显示出来
beginTransaction.show(mMessageFragment);
}
beginTransaction.addToBackStack(null);
break;
case 3:
//显示、加载Fragment
if (mMyFragment==null){
// 如果fragment为空,则创建一个并添加到界面上
mMyFragment=new MyFragment();
beginTransaction.add(R.id.frame_layout,mMyFragment);
}else {
// 如果Fragment不为空,则直接将它显示出来
beginTransaction.show(mMyFragment);
}
beginTransaction.addToBackStack(null);
break;
}
beginTransaction.commit();
}
/**
* BottomNavigationBar未被选中
* @param position
*/
@Override
public void onTabUnselected(int position) {
}
/**
* BottomNavigationBar重新选中
* @param position
*/
@Override
public void onTabReselected(int position) {
}
/**
* 隐藏 Fragment
* @param beginTransaction
*/
private void hideFragments(FragmentTransaction beginTransaction) {
if (mHomeFragment!=null){
beginTransaction.hide(mHomeFragment);
}
if (mShoppingCartFragment!=null){
beginTransaction.hide(mShoppingCartFragment);
}
if (mMessageFragment!=null){
beginTransaction.hide(mMessageFragment);
}
if (mMyFragment!=null){
beginTransaction.hide(mMyFragment);
}
}
}
其中 initView()方法体还可以这么写。
mBottomNavigationBar = (BottomNavigationBar) findViewById(R.id.bottom_navigation_bar);
//Background 模式
mBottomNavigationBar.setMode(BottomNavigationBar.MODE_FIXED);
//Background Style
mBottomNavigationBar.setBackgroundStyle(BottomNavigationBar.BACKGROUND_STYLE_STATIC);
mBottomNavigationBar
.addItem(new BottomNavigationItem(R.drawable.ic_home, "首页").
setInActiveColor(R.color.hei).setActiveColor(R.color.pink))
.addItem(new BottomNavigationItem(R.drawable.ic_cart, "购物车").
setInActiveColor(R.color.hei).setActiveColor(R.color.pink))
.addItem(new BottomNavigationItem(R.drawable.ic_mms, "消息").
setInActiveColor(R.color.hei).setActiveColor(R.color.pink))
.addItem(new BottomNavigationItem(getItem(R.drawable.ic_mine, "我的").
setInActiveColor(R.color.hei).setActiveColor(R.color.pink))
.setFirstSelectedPosition(0)//设置默认选择item
.setBarBackgroundColor(R.color.orange)//设置BottomNavigationBar的背景色
.initialise();//所有的设置需在调用该方法前完
或者这样写:
mBottomNavigationBar = (BottomNavigationBar) findViewById(R.id.bottom_navigation_bar);
//Background 模式
mBottomNavigationBar.setMode(BottomNavigationBar.MODE_FIXED);
//Background Style
mBottomNavigationBar.setBackgroundStyle(BottomNavigationBar.BACKGROUND_STYLE_STATIC);
mBottomNavigationBar
.addItem(new BottomNavigationItem(R.drawable.ic_home, "首页")
.addItem(new BottomNavigationItem(R.drawable.ic_cart, "购物车")
.addItem(new BottomNavigationItem(R.drawable.ic_mms, "消息")
.addItem(new BottomNavigationItem(getItem(R.drawable.ic_mine, "我的")
.setBarBackgroundColor(R.color.orange)//设置BottomNavigationBar的背景色
.setFirstSelectedPosition(0)//设置默认选择item
.setActiveColor(R.color.pink)//图标和文字的颜色一致(设置点击颜色)
.setInActiveColor(R.color.hei)//设置未点击颜色
.initialise();//所有的设置需在调用该方法前完
总结:
一:BottomNavigationBar Mode
Mode有三种:
- MODE_DEFAULT
如果Item的个数<=3就会使用MODE_FIXED模式,否则使用MODE_SHIFTING模式 - MODE_FIXED
填充模式,未选中的Item会显示文字,没有换挡动画。 - MODE_SHIFTING
换挡模式,未选中的Item不会显示文字,选中的会显示文字。在切换的时候会有一个像换挡的动画
二:Background Style
Style也有三种:
-
BACKGROUND_STYLE_DEFAULT
如果设置的Mode为MODE_FIXED,将使用BACKGROUND_STYLE_STATIC 。如果Mode为MODE_SHIFTING将使用BACKGROUND_STYLE_RIPPLE。 -
BACKGROUND_STYLE_STATIC
点击的时候没有水波纹效果 -
BACKGROUND_STYLE_RIPPLE
点击的时候有水波纹效果
三:BottomNavigationBar Item的选中和未选中颜色设置
//设置未点击颜色
mBottomNavigationBar.setInActiveColor(R.color.xxx);
//图标和文字的颜色一致(设置点击颜色)
mBottomNavigationBar.setActiveColor(R.color.xxx);
四:设置BottomNavigationBar的背景色
mBottomNavigationBar.setBarBackgroundColor(R.color.xxx);
五:添加标记小圆点
BadgeItem badgeItem = new BadgeItem();
badgeItem.setHideOnSelect(false)
.setText("10")
.setBackgroundColorResource(R.color.orange)
.setBorderWidth(0);
//导航栏中的tab添加小圆点
mBottomNavigationBar.addItem(new BottomNavigationItem(
R.drawable.ic_mms, "消息") .setActiveColorResource(R.color.green) .setBadgeItem(badgeItem));
。
。
。
最后注意:
所有的设置都要在.initialise();之前完成。
官网例子地址:
https://github.com/Ashok-Varma/BottomNavigation