BottomNavigationView 这个官方控件出了几个月了,也有一些介绍该控件的文章,但我发现大部分博文只是做了简单的用法介绍,并未解决一些需求,比如:取消位移动画、和ViewPager一起使用、加入Badge。所以我又写了这么一篇博客。
2. 在 xml 中使用库
<android.support.design.widget.BottomNavigationView
android:id="@+id/bnve"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:background="@color/colorPrimary"
app:itemIconTint="@color/selector_item_color"
app:itemTextColor="@color/selector_item_color"
app:menu="@menu/menu_navigation_with_view_pager" />复制代码
background
: 控件背景
app:itemBackground
: 子菜单背景
app:itemIconTint
: 图标颜色
app:itemTextColor
: 文本颜色
app:menu
: 菜单
这里我把背景设置成主色调 colorPrimary,图标和文本设置为一样的颜色 selector_item_color,具体内容如下:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="#fff" android:state_checked="true"/>
<item android:color="#fff" android:state_pressed="true"/>
<item android:color="#bbb"/>
</selector>复制代码
也就是选中的时候是白色,默认为灰色。
最后是菜单
menu_navigation_with_view_pager
,和普通菜单一样。
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
android:id="@+id/menu_music"
android:checked="true"
android:icon="@drawable/ic_audiotrack_black_24dp"
android:title="@string/music" />
android:id="@+id/menu_backup"
android:icon="@drawable/ic_backup_black_24dp"
android:title="@string/backup" />
android:id="@+id/menu_friends"
android:icon="@drawable/ic_camera_black_24dp"
android:title="@string/friends" />
</menu>复制代码
菜单的图片建议用矢量图片,也就是 svg 导入后的xml文件。
最后运行出来是这样的。
看到这里,我只能说,没毛病。
3. 方法
如果去看类的文档,就会发现,公开的方法中,常用的就只有
setOnNavigationItemSelectedListener
。
也就是设置一个点击的监听器。
bnve.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
Log.d(TAG, item.getItemId() + " item was selected-------------------");
return true;
});复制代码
回调方法有个返回值,如果返回 false,则你的点击会被取消,也就是不会切换到下一个菜单。
回调方法中给的参数是
MenuItem
,你可以获取到被点击菜单的 id,也就是你可以这么做。
int id = 0
switch (item.getItemId()) {
case R.id.menu_music:
id = 0
break
case R.id.menu_backup:
id = 1
break
case R.id.menu_friends:
id = 2
break
vp.setCurrentItem(id, false)复制代码
貌似依旧没毛病,官方的库用法简单实用。
1. BottomNavigationView
进入
BottomNavigationView
,发现最主要的成员是下面两个,由变量命名可以猜测出分别是作为视图和控制器。
private final BottomNavigationMenuView mMenuView;
private final BottomNavigationPresenter mPresenter = new BottomNavigationPresenter();复制代码
然后看构造方法,是把
mMenuView
添加到Layout里了。所以,如果想要了解界面怎么显示的,还得分析
BottomNavigationMenuView
。
addView(mMenuView, params);复制代码
2. BottomNavigationMenuView
通过对成员变量的粗略查看,发现以下几个关键的成员。
private final OnClickListener mOnClickListener;
private boolean mShiftingMode = true;
private BottomNavigationItemView[] mButtons;复制代码
然后再看构造函数,设置了一个点击监听器,接收到的是
BottomNavigationItemView
,处理的是点击子菜单的事件。
mOnClickListener = new OnClickListener() {
@Override
public void onClick(View v) {
final BottomNavigationItemView itemView = (BottomNavigationItemView) v
final int itemPosition = itemView.getItemPosition()
if (!mMenu.performItemAction(itemView.getItemData(), mPresenter, 0)) {
activateNewButton(itemPosition)
}复制代码
然而这里并没有直接的对
mButtons
赋值,这个时候就应该去找 presenter,对MVP熟悉的就知道, presenter 负责把 M 和 V 联系起来。
在 presenter 的
updateMenuView
方法中调用了 mMenuView 中的
updateMenuView
去创建 mButtons。而 BottomNavigationView
中负责调用 presenter。
具体调用顺序如下: