BottomNavigationView应用及其添加角标

BottomNavigationView的使用规范:

1:官方建议item个数为3-5个 ,尝试6个会直接报错,尝试2个则不会报错,但是item是2个的话不建议使用改控件

2:底部导航栏的高度建议是56dp

一、简单的实现,先看效果图


首先添加依赖:${SUPPORT_LIBRARY_VERSION}为最新版本号,修改之后直接导入即可,即可愉快使用

compile'com.android.support:design:${SUPPORT_LIBRARY_VERSION}'

compile'com.android.support:support-v4:${SUPPORT_LIBRARY_VERSION}'

布局代码如下:

<android.support.design.widget.BottomNavigationView
            android:id="@+id/bottom_navigation"
            style="@style/Widget.Design.BottomNavigationView"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:layout_gravity="bottom"
            android:background="@color/viewBackground"
            app:itemIconTint="@drawable/nav_item_color_state"
            app:itemTextColor="@drawable/nav_item_color_state"
            app:menu="@menu/bottom_navigation_main"/>

大家看到了app:menu属性,官方文档的问题在于指定了一个固定的包名使用时需要绑定http://schemas.android.com/apk/res-auto
app:itemIconTint: 设置菜单图标着色
app:itemTextColor:设置菜单文本颜色
app:menu:设置菜单
更多属性可查看官方文档:https://www.google.com/design/spec/components/bottom-navigation.html#bottom-navigation-u
bottom_navigation_main菜单文件根据自己需求设置。

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:app="http://schemas.android.com/apk/res-auto">
    <item
        android:id="@+id/action_news"
        android:enabled="true"
        android:icon="@drawable/ic_newspaper_white_24dp"
        android:title="@string/title_news"
        app:showAsAction="ifRoom"/>
    <item
        android:id="@+id/action_photo"
        android:enabled="true"
        android:icon="@drawable/ic_gallery_white_24dp"
        android:title="@string/title_photo"
        app:showAsAction="ifRoom"/>
    <item
        android:id="@+id/action_video"
        android:enabled="true"
        android:icon="@drawable/ic_youtube_white_24dp"
        android:title="@string/title_video"
        app:showAsAction="ifRoom"/>
    <item
        android:id="@+id/action_media"
        android:enabled="true"
        android:icon="@drawable/ic_library_books_white_24dp"
        android:title="@string/title_media"
        app:showAsAction="ifRoom"/>
</menu>

以上就实现了BottomNavigationView的简单实用。

二、大家可能注意到了当菜单项多于3个时,效果和3个及以下的效果已经完全不一样了,只有选中的菜单项才会显示出文字,未选中的菜单项只显示图标。很明显不符合产品需求,本来以为BottomNavigationView应该有自定义的方法可以改变这种默认的行为,结果人家官方压根没有提供,在stackoverflow上找到的最佳方案也是使用反射。

看效果图创建一个helper类

import android.annotation.SuppressLint;
import android.support.design.internal.BottomNavigationItemView;
import android.support.design.internal.BottomNavigationMenuView;
import android.support.design.widget.BottomNavigationView;
import android.util.Log;
import java.lang.reflect.Field;

public class BottomNavigationViewHelper {

    @SuppressLint("RestrictedApi")
    public static void disableShiftMode(BottomNavigationView view) {
        //Acquisition child View BottomNavigationMenuView Objects
        BottomNavigationMenuView menuView = (BottomNavigationMenuView) view.getChildAt(0);
        try {
            //Setting private member variables mShiftingMode Can be modified
            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) {
            Log.e("BNVHelper", "Unable to get shift mode field", e);
        } catch (IllegalAccessException e) {
            Log.e("BNVHelper", "Unable to change value of shift mode", e);
        }
    }
}

然后在获取控件之后直接应用就可以了

BottomNavigationView bottom_navigation = findViewById(R.id.bottom_navigation);
BottomNavigationViewHelper.disableShiftMode(bottom_navigation);

三、这个时候需求又来了,项目中实现了IM,需要即时显示消息未读数量,这个时候怎么办呢?经过探查源码发现BottomNavigationMenuView中的每一个Tab就是一个FrameLayout,所以我们可以在上面随意添加View、这样我们就可以轻松的实现了。


//获取整个的NavigationView
BottomNavigationMenuView menuView = (BottomNavigationMenuView) bottom_navigation.getChildAt(0);
//这里就是获取所添加的每一个Tab(或者叫menu),
View tab = menuView.getChildAt(3);
BottomNavigationItemView itemView = (BottomNavigationItemView) tab;
//加载我们的角标View,新创建的一个布局
View badge = LayoutInflater.from(this).inflate(R.layout.im_badge, menuView, false);
//添加到Tab上
itemView.addView(badge);
TextView textView = badge.findViewById(R.id.texT);
textView.setText(String.valueOf(1));
//无消息时可以将它隐藏即可
textView.setVisibility(View.VISIBLE);

代码很简单非常容易理解,至于im_badge布局文件我就不贴了,里面只是一个TextView,样式都可以自己根据需求随意设置。

如有问题请即时留言

  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值