安卓 BottomNavigationBar 底部导航的使用

简介:Google推出的BottomNavigationBar底部导航栏

  • 1 、基本的使用(add和replace方式)
  • 2、扩展添加消息和图形
  • 3、修改图片大小与文字间距

版本更新:2019-5-13
补充布局文件activity_main




    

    

    


1、默认使用studio背景图,防止少图片资源(效果图虽不尽人意~)
安卓 BottomNavigationBar 底部导航的使用_第1张图片

2、项目build.gradle添加依赖:(注意studio3.0以下将implementation 换成 compile)

    implementation 'com.ashokvarma.android:bottom-navigation-bar:2.0.4'

3、MainActivity

import android.graphics.Color;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.ashokvarma.bottomnavigation.BottomNavigationBar;
import com.ashokvarma.bottomnavigation.BottomNavigationItem;
import com.ashokvarma.bottomnavigation.ShapeBadgeItem;
import com.ashokvarma.bottomnavigation.TextBadgeItem;

import java.lang.reflect.Field;

public class MainActivity extends AppCompatActivity implements BottomNavigationBar.OnTabSelectedListener {

    private FragmentManager mFragmentManager;
    private BottomNavigationBar bottomNavigationBar;

    private FirstFragment firstFragment;
    private SecondFragment secondFragment;
    private ThirdFragment thirdFragment;
    private FourthFragment fourthFragment;
    //默认选择第一个fragment
    private int lastSelectedPosition = 0;
    private FragmentTransaction transaction;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        bottomNavigationBar = this.findViewById(R.id.bottomNavigationBar);
        showNumberAndShape();
        initNavigation();
    }

    /**
     * 初始底部导航栏
     */
    private void initNavigation() {
        //导航栏Item的个数<=3 用 MODE_FIXED 模式,否则用 MODE_SHIFTING 模式
        bottomNavigationBar.setMode(BottomNavigationBar.MODE_FIXED);
        bottomNavigationBar.setTabSelectedListener(this);//监听切换点击事件
        //bottomNavigationBar.setBarBackgroundColor("#595757");//背景颜色
        //1、BACKGROUND_STYLE_DEFAULT:如果设置的Mode为MODE_FIXED,将使用BACKGROUND_STYLE_STATIC 。如果Mode为MODE_SHIFTING将使用BACKGROUND_STYLE_RIPPLE。
        //2、BACKGROUND_STYLE_STATIC:点击无水波纹效果
        //3、BACKGROUND_STYLE_RIPPLE:点击有水波纹效果
        bottomNavigationBar.setBackgroundStyle(BottomNavigationBar.BACKGROUND_STYLE_STATIC);
        //需要添加的item数
        bottomNavigationBar
                //选中时的图片的资源、文字
                .addItem(new BottomNavigationItem(R.drawable.home, "首页")
                        //选中的颜色
                        .setActiveColor(R.color.colorAccent)
                        //选中的颜色(资源文件 下面同上)
                        //.setActiveColorResource(R.color.colorAccent)
                        //未选中的颜色(默认灰色 可注释)
                        .setInActiveColor("#999999")
                        //未选中时的图片的资源
                        .setInactiveIconResource(R.drawable.ic_launcher_background))
                .addItem(new BottomNavigationItem(R.drawable.home, "订单")
                        .setActiveColorResource(R.color.colorAccent)
                        .setInActiveColor("#999999")
                        .setInactiveIconResource(R.drawable.ic_launcher_background)).
                addItem(new BottomNavigationItem(R.drawable.ic_launcher_background, "购物车")
                        .setActiveColorResource(R.color.colorAccent)
                        .setInActiveColor("#999999")
                        .setBadgeItem(textBadgeItem)
                        .setInactiveIconResource(R.drawable.ic_launcher_background)).
                addItem(new BottomNavigationItem(R.drawable.ic_launcher_background, "我的")
                        .setActiveColorResource(R.color.colorAccent)
                        .setInActiveColor("#999999")
                        .setBadgeItem(shapeBadgeItem)
                        .setInactiveIconResource(R.drawable.ic_launcher_background))
                .setFirstSelectedPosition(lastSelectedPosition)//设置默认选中项
                //.setFab(FloatingActionButton的id)//FloatingActionButton 关联
                .initialise();//注意此句放在最后
        setIconItemMargin(bottomNavigationBar,10,25,14);
        setDefaultFragment();
    }

    /**
     * 设置默认开启的fragment
     */
    private void setDefaultFragment() {
        mFragmentManager = getSupportFragmentManager();
        FragmentTransaction transaction = mFragmentManager.beginTransaction();
        firstFragment = new FirstFragment();
        transaction.add(R.id.tb, firstFragment);
        transaction.commit();
    }

    /**
     * 切换事件
     */
    @Override
    public void onTabSelected(int position) {
        lastSelectedPosition = position;//每次点击赋值
        //开启事务
        transaction = mFragmentManager.beginTransaction();
        hideFragment(transaction);
        switch (position) {
            case 0:
                if (firstFragment == null) {
                    firstFragment = new FirstFragment();
                    transaction.add(R.id.tb, firstFragment);
                } else {
                    transaction.show(firstFragment);
                }
                // transaction.replace(R.id.tb, firstFragment);
                break;
            case 1:
                if (secondFragment == null) {
                    secondFragment = new SecondFragment();
                    transaction.add(R.id.tb, secondFragment);
                } else {
                    transaction.show(secondFragment);
                }
                break;
            case 2:
                if (thirdFragment == null) {
                    thirdFragment = new ThirdFragment();
                    transaction.add(R.id.tb, thirdFragment);
                } else {
                    transaction.show(thirdFragment);
                }
                break;
            case 3:
                if (fourthFragment == null) {
                    fourthFragment = new FourthFragment();
                    transaction.add(R.id.tb, fourthFragment);
                } else {
                    transaction.show(fourthFragment);
                }
                break;
        }
        // 事务提交
        transaction.commit();
    }

    /**
     * 隐藏当前fragment
     *
     * @param transaction
     */
    private void hideFragment(FragmentTransaction transaction) {
        if (firstFragment != null) {
            transaction.hide(firstFragment);
        }
        if (secondFragment != null) {
            transaction.hide(secondFragment);
        }
        if (thirdFragment != null) {
            transaction.hide(thirdFragment);
        }
        if (fourthFragment != null) {
            transaction.hide(fourthFragment);
        }
    }

    private TextBadgeItem textBadgeItem;
    private ShapeBadgeItem shapeBadgeItem;

    /**
     * 展示消息点
     */
    private void showNumberAndShape() {
        //消息
        textBadgeItem = new TextBadgeItem()
                .setText("99")//显示的文本
                .setTextColor("#ffffff")//文本颜色
                //.setTextColorResource(R.color.colorAccent)//文本颜色(资源文件-下面如同)
                .setBorderWidth(6)//圆环宽度
                .setBorderColor(Color.parseColor("#000000"))//圆环燕色
                //.setBorderColorResource(R.color.colorPrimary)
                .setBackgroundColor("#FF4081")//背景颜色
                .setHideOnSelect(false);//选中是否隐藏
        //.setBackgroundColorResource(R.color.colorAccent)//背景颜色
        //.setAnimationDuration(300)//隐藏与动画的过渡时间(setHideOnSelect 为true时生效)
        //.setGravity(Gravity.RIGHT | Gravity.TOP); //位置,默认右上角(可不设置)

        //形状
        shapeBadgeItem = new ShapeBadgeItem()
                //也可设置为常量 (0-6之间)
                .setShape(ShapeBadgeItem.SHAPE_HEART) //形状
                .setShapeColor(Color.RED) //颜色
                //.setShapeColorResource(R.color.colorPrimaryDark) //(同上)
                .setEdgeMarginInDp(this, 0) //距离Item的边距,dp值
                //.setEdgeMarginInPixels(20) //距离Item的边距,px
                .setSizeInDp(this, 15, 15) //宽高值,dp
                //.setSizeInPixels(30, 30) //宽高值,px
                .setAnimationDuration(300) //隐藏和展示的动画速度,单位毫秒,和setHideOnSelect一起使用
                //.setGravity(Gravity.LEFT) //位置,默认右上角
                .setHideOnSelect(false); //true:当选中状态时消失,非选中状态显示,moren false
    }

    @Override
    public void onTabUnselected(int position) {
    }

    @Override
    public void onTabReselected(int position) {
    }

    /**
     * 修改间距及图片文字大小
     * @param bottomNavigationBar
     * @param space  文字与图片的间距
     * @param imgLen  单位:dp,图片大小
     * @param textSize 单位:dp,文字大小
     */
    private void setIconItemMargin(BottomNavigationBar bottomNavigationBar, int space, int imgLen, int textSize){
        Class barClass = bottomNavigationBar.getClass();
        Field[] fields = barClass.getDeclaredFields();
        for(int i = 0; i < fields.length; i++){
            Field field = fields[i];
            field.setAccessible(true);
            if(field.getName().equals("mTabContainer")){
                try{
                    //反射得到 mTabContainer
                    LinearLayout mTabContainer = (LinearLayout) field.get(bottomNavigationBar);
                    for(int j = 0; j < mTabContainer.getChildCount(); j++){
                        //获取到容器内的各个Tab
                        View view = mTabContainer.getChildAt(j);
                        //获取到Tab内的各个显示控件
                        FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, dip2px(56));
                        FrameLayout container = (FrameLayout) view.findViewById(R.id.fixed_bottom_navigation_container);
                        container.setLayoutParams(params);
                        container.setPadding(dip2px(12), dip2px(0), dip2px(12), dip2px(0));

                        //获取到Tab内的文字控件
                        TextView labelView = (TextView) view.findViewById(com.ashokvarma.bottomnavigation.R.id.fixed_bottom_navigation_title);
                        //计算文字的高度DP值并设置,setTextSize为设置文字正方形的对角线长度,所以:文字高度(总内容高度减去间距和图片高度)*根号2即为对角线长度,此处用DP值,设置该值即可。
                        labelView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, textSize);
                        labelView.setIncludeFontPadding(false);
                        labelView.setPadding(0,0,0,dip2px(20-textSize - space/2));

                        //获取到Tab内的图像控件
                        ImageView iconView = (ImageView) view.findViewById(com.ashokvarma.bottomnavigation.R.id.fixed_bottom_navigation_icon);
                        //设置图片参数,其中,MethodUtils.dip2px():换算dp值
                        params = new FrameLayout.LayoutParams(dip2px(imgLen), dip2px(imgLen));
                        params.setMargins(0,0,0,space/2);
                        params.gravity = Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL;
                        iconView.setLayoutParams(params);
                    }
                } catch (IllegalAccessException e){
                    e.printStackTrace();
                }
            }
        }
    }

    private int dip2px(float dpValue) {
        final float scale = getApplication().getResources().getDisplayMetrics().density;
        return (int) (dpValue * scale + 0.5f);
    }
}

其中有4个碎片在这只贴出FirstFragment (其余几乎一致)

4、FirstFragment

import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class FirstFragment extends Fragment {

    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

        View view = inflater.inflate(R.layout.activity_first_fragment, container, false);

        return view;
    }
}

注意引用V4的包

其布局:activity_first_fragment




    


5、若要使用replace的显示方式,将onTabSelected监听处改为如下代码即可

1、switch处

 switch (position) {
            case 0:
                firstFragment = new FirstFragment();
                transaction.replace(R.id.tb, firstFragment);
                break;
            case 1:
                secondFragment = new SecondFragment();
                transaction.replace(R.id.tb, secondFragment);
                break;
            case 2:
                thirdFragment = new ThirdFragment();
                transaction.replace(R.id.tb, thirdFragment);
                break;
            case 3:
                fourthFragment = new FourthFragment();
                transaction.replace(R.id.tb, fourthFragment);
                break;
        }

2、注释 //hideFragment(transaction);这个方法

6、最后贴出TextBadgeItem和ShapeBadgeItem的属性图

安卓 BottomNavigationBar 底部导航的使用_第2张图片

安卓 BottomNavigationBar 底部导航的使用_第3张图片

你可能感兴趣的:(安卓开发)