BottomNavigationView的学习使用

介绍

效果图

基本上每个应用都有这样的需求,之前通过RadioGroup加RadioButton配合来实现,现在采用design包下的BottomNavigationView来完成.

写在前面

他只能支持3到5个按钮的操作,如果再多,请选择其他替代品.

在xml文件中直接使用

 

对于关键属性进行解答:

app:itemIconTint="@color/testc"

表示icon的颜色,其并不是单一 的color,而是一个selector,表示选中与不选中时候的图标的颜色,比如下面的方式:



    
    

app:itemTextColor="@color/testc"

表示text的颜色,其也不是单一的颜色,也是selector,表示文字按下与抬起的颜色.



    
    

app:itemBackground="@color/colorWrite"

表示正哥底部导航栏的颜色

app:menu="@menu/navigation"

需要你在res/创建menu文件夹,然后创建xml文件




    

    

    
    


这里有四个item.表明,你想让底部展示四个按钮用于切换.
每一个item包含:

id : 表示当前item的id,为以后的点击事件作准备
icon : 表示的是每一个item上的图,这里可不是单纯的图片如果你使用一般的图片,那么运行完程序,
你会发现,这个icon地方变成圆形的按钮,然后用户选中与不选中颜色就是上面xml中设置的颜色.
这个icon必须是vector 的Drawable.
title:就是每一个条目展示的名字
一般设计成这个样子,是为了上面完成切换页面的任务,那么就有了下面的监听
   bottomNavigationView.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
            @Override
            public boolean onNavigationItemSelected(@NonNull MenuItem item) {
                               //如果用户已经选择了当前item,那么用户再点击次item,这个方法不会调用.
                           return false;
            }
        });

在这个接口回调中,可以同item.getItemId来区分用户选中的是哪一个item

另外他还提供了如下几个比较好的方法:

(1) bottomNavigationView.setSelectedItemId();

此方法可以直接使得哪一个item被选中,需要注意的是,当你调用这个之后,仍会走setOnNavigationItemSelectedListener的回调.

(2) 具体如下:

 bottomNavigationView.setOnNavigationItemReselectedListener(new BottomNavigationView.OnNavigationItemReselectedListener() {
            @Override
            public void onNavigationItemReselected(@NonNull MenuItem item) {
                //用户选中了当前item,再点击当前item时候的回调.
            }
        });

问题

如果你设置的底部的item数量超过三个,如果不做处理的话,你会发现,他们并不均分底部空间,这样效果很不好,所以利用反射去除掉:

public class BottomNavigationViewHelper {
    @SuppressLint("RestrictedApi")
    public static void disableShiftMode(BottomNavigationView view) {
        BottomNavigationMenuView menuView = (BottomNavigationMenuView) view.getChildAt(0);
        try {
            Field shiftingMode = menuView.getClass().getDeclaredField("mShiftingMode");
            shiftingMode.setAccessible(true);
            shiftingMode.setBoolean(menuView, false);
            shiftingMode.setAccessible(false);
            for (int i = 0; i < menuView.getChildCount(); i++) {
                BottomNavigationItemView item = (BottomNavigationItemView) menuView.getChildAt(i);
                //noinspection RestrictedApi
                item.setShiftingMode(false);
                // set once again checked value, so view will be updated
                //noinspection RestrictedApi
                item.setChecked(item.getItemData().isChecked());
            }
        } catch (NoSuchFieldException e) {

        } catch (IllegalAccessException e) {

        }
    }

    //调整底部导航栏图标大小
    public static void adjustNavigationButtonView(BottomNavigationView bottomNavigationView, Context context) {
        BottomNavigationMenuView menuView = (BottomNavigationMenuView) bottomNavigationView.getChildAt(0);
        for (int i = 0; i < menuView.getChildCount(); i++) {
            View iconView = menuView.getChildAt(i).findViewById(android.support.design.R.id.icon);
            ViewGroup.LayoutParams layoutParams = iconView.getLayoutParams();
            DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
            layoutParams.height = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 20, displayMetrics);
            layoutParams.width = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 20, displayMetrics);
            iconView.setLayoutParams(layoutParams);
        }
    }
}

在28以上,google提供了方法的支持,再通过上述放射的方式实现,就不可以了,具体如下:

app:labelVisibilityMode="[labeled, unlabeled, selected, auto]"
labeled : 保持所有文字便签显示
unlabeled :只显示图标
selected :在选中的时候显示文字标签,有动画效果
auto : 在 1-3 个按钮时使用 labeled ,大于 3 个按钮使用 selected

或者

navigation.setLabelVisibilityMode(LabelVisibilityMode.LABEL_VISIBILITY_LABELED);
我在28api的模拟器上运行,并未发现问题问题,可能是当前应用未兼容到28以上的原因.

取消导航栏图标着色

navigation.setItemIconTintList(null);

补充:如果你打包的时候要开启不混淆如下:

-keep public class android.support.design.** {*;} 
//为了省事,直接开启design包不混淆

特别感谢:

BottomNavigationView 的使用及遇到的坑
BottomNavigationView图标大小和颜色设置

持续更新,诸位遇到问题可以留言,我也研究研究,共同学习,谢谢啦.

你可能感兴趣的:(BottomNavigationView的学习使用)