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-ubottom_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,样式都可以自己根据需求随意设置。
如有问题请即时留言