Android BottomNavigationView,底部导航栏的简单实现

11,976 阅读4分钟

关于 Material Design 相关的控件,之前整理了一个系列文章,并在 GitHub 上建立一个 MDSamples 工程,使用代码和文字解说配合的方式逐一说明。截止目前,大致写有八九篇文章。期间,由于一些工作变动和琐事,停了一些时间。现在,有点时间,准备续上。

之前的文章,参考列表如下:

这一篇要说的是 Android App 中的 BottomNavigation 设计,底部导航栏,设计规范可参考官网:

Material Design Components 之 Bottom Navigation

support.design 包中对应提供的控件是 BottomNavigationView,提供不多于 5 个菜单的底部导航栏实现。

我们先来看一下基本使用:

<android.support.design.widget.BottomNavigationView
    android:id="@+id/bnv_menu"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    app:itemIconTint="@color/selector_blue"
    app:itemTextColor="@color/selector_blue"
    app:menu="@menu/menu_bottom_navigation"/>

使用 menu 资源定义菜单内容,也就是这里的 res/menu/menu_bottom_navigation.xml 文件:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">

    <item
        android:id="@+id/action_home"
        android:title="Home"
        android:icon="@drawable/ic_action_home"/>

    <item
        android:id="@+id/action_explore"
        android:title="Explore"
        android:icon="@drawable/ic_action_explore"/>

    <item
        android:id="@+id/action_me"
        android:title="Me"
        android:icon="@drawable/ic_action_me"/>

</menu>

除了 app:menu 属性定义菜单内容,BottomNavigationView 能够使用的定制属性并不多,有这几个:

app:itemIconTint:Icon 图标着色,值为一个 ColorStateList ,可以在 color 资源文件夹中定义。使用这个属性,奇妙利用 tint 着色器实现一个图标多种状态下使用。:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:state_checked="true" android:color="@color/blue"></item>
    <item android:color="@color/gray"></item>

</selector>

app:itemTextColor:Label 文字颜色定义。

app:itemBackground:背景内容。

效果如下:

上图是 3 个菜单时的展示和交互方式,即菜单文字和图标同时显示,选中时有一个大小变化过程(这里不是动画,通过源码可以看到,其实只是一个简单的尺寸上的瞬时缩放)。但是,当超过 3 个菜单时,文字就不再显示。对比看一下 5 个菜单时的效果图:

可以看到,交互方式也发生变化,选中有一个左右移动腾出空间的过程。那再多一点菜单数量,比如 6 个时呢?对不起,要报错啦,不支持!

注意:根据 Material Design 对底部导航栏的设计要求,BottomNavigationView 只支持 3 到 5 个子菜单数量的导航栏。并且,考虑到用户体验,3 个及3个以下菜单数量的导航栏,与超过 3 个时,交互过程也有所区分。关于最多支持 5 个字菜单的内容,可以从 BottomNavigationView 源码中查看:
public static final int MAX_ITEM_COUNT = 5;
当超出这个数量时,产生非法参数异常。

通过 setOnNavigationItemSelectedListener() 方法可以监听不同子菜单的选中切换事件。但是,竟然没有一个简便的方法直接设置选中某个子菜单,就像 check(id) 这样。不知是不是 BottomNavigationView 控件设计时的遗漏。目前能够想到的一个做法就是获取 menu item 对象,利用 performClick() 模拟点击事件,如:

BottomNavigationView view = (BottomNavigationView) findViewById(R.id.bnv_menu);
view.findViewById(R.id.action_explore).performClick();

以上便是 BottomNavigationView 的所有内容,按照 Android 上的 Bottom Navigation 设计规范定制而成。可以看出,使用起来还是很简单的。同时,可定制性也非常有限。比如,想在底部某个子菜单添加一个小红点提示的视图,就有些难以处理。如果使用 RadioGroup 实现导航栏的话,就灵活一些。

附:GitHub 站有一个 BottomNavigationBar 开源项目,专门针对 Material Design 风格的 Bottom Navigation 量身定制的,可供参考。

关于我:亦枫,博客地址:yifeng.studio/,新浪微博:IT亦枫

微信扫描二维码,欢迎关注我的个人公众号:安卓笔记侠

不仅分享我的原创技术文章,还有程序员的职场遐想