Material Design 组件之NavigationView

原文首发于微信公众号:jzman-blog,欢迎关注交流!

Material Design 系列文章:

今天来看一下 NavigationView 的使用,NavigationView 是一个标准的导航菜单,其菜单内容由菜单资源文件来填充,NavigationView 一般和 DrawerLayout 一起搭配使用构成抽屉菜单,分别由内容页和菜单页组成。主要内容如下:

  1. 基本布局
  2. 常用属性
  3. 文字选中效果
  4. 图标与文字间距
  5. 案例
  6. 显示效果

基本布局

可以直接使用 DrawerLayout 作为根布局,里面依次是内容布局和菜单布局,切记内容布局一定是在菜单布局的前面,可以这样理解菜单划出的时候肯定应该在内容布局之上,如果两者顺序相反,则影响菜单 Item 的点击事件以及菜单的滑动隐藏,当然如果有 ToolBar 等,可以按需添加到内容布局中,也可以 DrawerLayout 外,唯一区别是侧换菜单是否遮挡 ToolBar,基本使用参考如下:

 <android.support.v4.widget.DrawerLayout  
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto"
     android:id="@+id/drawer_layout"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:fitsSystemWindows="true">
     
     <!--内容 -->
     
     <!--菜单-->
     <android.support.design.widget.NavigationView
         android:id="@+id/navigation"
         android:layout_width="wrap_content"
         android:layout_height="match_parent"
         android:layout_gravity="start"
         app:menu="@menu/my_navigation_items" />
 </android.support.v4.widget.DrawerLayout>

常用属性

下面是 NavigationView 的常用属性,具体如下:

<!--菜单弹出方向-->
android:layout_gravity="start"
<!--菜单图标渲染的颜色-->
app:itemIconTint="@color/colorPrimary"
<!--菜单文字的颜色-->
app:itemTextColor="@color/colorNormal"
<!--菜单项背景颜色(组之间有间隔)-->
app:itemBackground="@color/colorBackground"
<!--菜单项-->
app:menu="@menu/menu_navigation_view" 
<!--NavigationView的头部布局-->
app:headerLayout="@layout/head_navigation_layout"

文字选中效果

如果美工比较用心会告诉点击时是那种颜色、按下是那种颜色或者是某种效果,此时就需要设置菜单项文字选中效果了,这里选择创建在 color 资源文件的形式来实现文字选中效果了,定义 color 资源文件如下:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <!--按下-->
    <item android:color="@color/colorPress" android:state_pressed="true"/>
    <!--选中-->
    <item android:color="@color/colorCheck" android:state_checked="true"/>
    <!--默认-->
    <item android:color="@color/colorNormal"/>
</selector>

然后,设置 NavigationView 的 itemTextColor 属性即可,具体如下:

<!--设置菜单项颜色-->
app:itemTextColor="@color/select_color_navigation"

当然,也可以在代码中设置,具体如下:

//设置菜单项颜色
ColorStateList colorStateList = getResources().getColorStateList(R.color.select_color_navigation);
navigationView.setItemTextColor(colorStateList);

然后,设置对 NavigationView 菜单项选中的事件监听,具体如下:

navigationView.setNavigationItemSelectedListener(this);

最后,在点击完成要设置该菜单项已被选中,具体如下:

@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {

    switch (item.getItemId()){
        case R.id.menu1:
            Toast.makeText(this,"menu1",Toast.LENGTH_SHORT).show();
            break;
        //...
    }
    //设置菜单项选中
    item.setCheckable(true);
    //关闭Drawer
//    navDrawLayout.closeDrawers();
    return true;
}

图标与文字间距

使用 NavigationView 之后发现,菜单图标与菜单文字之间有一定的间距,看着有点宽,有一点强迫症必须稍微修改小一点,根据之前修改 FloatingActionButton 大小的经验,翻一下源码找设置这个间距的位置,查看 NavigationView 源码,最终在 NavigationMenuPresenter 中找到相关的 dimen 值,然后顺藤摸瓜找到与 Navigation 相关的几个 dimen 值,具体如下:

public static final int design_navigation_elevation = 0x7f060064;
public static final int design_navigation_icon_padding = 0x7f060065;
public static final int design_navigation_icon_size = 0x7f060066;
public static final int design_navigation_max_width = 0x7f060067;
public static final int design_navigation_padding_bottom = 0x7f060068;
public static final int design_navigation_separator_vertical_padding = 0x7f060069;

此时,在项目的 dimens 文件夹中创建名称相同的值覆盖即可,这里是修改 Menu 图标与文字之间的间距,所以我们只要设置:

<!--修改NavigationView菜单图标与文字之间的间距-->
<dimen name="design_navigation_icon_padding" tools:override="true">10dp</dimen>

至于其他相关的 dimen 值就不一一说明了,这样就修改了 Menu 图标与文字之间的间距。

案例

下面是一个 NavigationView 结合 DrawerLayout 的使用案例,布局如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    <!--ToolBar-->
    <android.support.v7.widget.Toolbar
        android:id="@+id/navToolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="@color/colorPrimary" />

    <android.support.v4.widget.DrawerLayout
        android:id="@+id/navDrawLayout"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <!--内容-->
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">
            <TextView
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:gravity="center"
                android:text="@string/app_name"
                android:textSize="18sp" />
        </LinearLayout>
        <!--菜单-->
        <android.support.design.widget.NavigationView
            android:id="@+id/navigationView"
            android:layout_width="200dp"
            android:layout_height="match_parent"
            android:layout_gravity="start"
            app:headerLayout="@layout/head_navigation_layout"
            app:itemIconTint="@color/colorPrimary"
            app:itemTextColor="@color/select_color_navigation"
            app:menu="@menu/menu_navigation_view" />
    </android.support.v4.widget.DrawerLayout>

</LinearLayout>

显示效果

下面是显示效果,如下图所示:

clipboard.png

最近总结了一下 Material Design 组件的使用,可以选择关注微信公众号:jzman-blog 获取最新更新,可以在公众号回复关键字 MD 获取相关代码链接。
jzman-blog


躬行之
个人公众号:躬行之(jzmna-blog),推送原创Android技术文章,不限于生活、职场等,不定期更新。
18 声望
5 粉丝
0 条评论
推荐阅读
设计模式之代理设计模式
今天来看一下什么是代理设计模式,顾名思义,代理就是通过中介代替某人做某一件事,对应到我们的程序中就是通过代理对象来控制某个具体对象某个方法的访问,在该方法之前和之后可以做一些额外处理。

躬行之阅读 1.2k

封面图
网易云音乐开源全链路埋点方案-曙光埋点(dawn)
网易云音乐开源了曙光埋点 dawn,一个跨多端的全链路埋点解决方案,旨在构造一个完美的数据理想国。曙光埋点创造性的提出了埋点虚拟树(VTree),并在此基础上实现了诸多能力,解决大前端侧埋点困难、精度差、不...

云音乐技术团队3阅读 2.4k

封面图
深入探讨安卓UI线程与子线程交互5大设计
在一个Android 程序开始运行的时候,会单独启动一个Process。默认的情况下,所有这个程序中的Activity或者Service(Service和 Activity只是Android提供的Components中的两种,除此之外还有Content Provider和Broa...

糖墨夕1阅读 5.2k

直播回顾 | 点击率提升400%,Ta是怎么做到的?
Discovery第18期直播已于3月30日圆满结束,本期直播邀请天眼查做客直播间,从天眼查与华为Push用户增长服务合作历程切入,聚焦用户增长,分享提升应用活跃度和渠道ROI的经验与见解。一起来回顾本期精彩内容吧!

HMSCore阅读 6.4k

Android Crash 前的最后抢救
众所周知,当 Andoird 程序发生未捕获的异常的时候,程序会直接 Crash 退出。而所谓安全气囊,是指在 Crash 发生时捕获异常,然后触发兜底逻辑,在程序退出前做最后的抢救。

xiangzhihong1阅读 1.3k

教你如何在 Andorid 上使用OpenAI API 调用ChatGpt
现在Chat GPT功能越来越强了,几乎你想问实际问题它都能给你回答。正好,小组结课的 Android项目 有一个解梦的功能。正好调用chatGpt的Api来实现。下面就来简单实现在Andorid项目中打造一个简易的聊天机器人。

weiweiyi1阅读 987

Linux下编译WebRTC(Linux和Android版本)
随着新冠疫情的影响,这两年音视频的需求呈爆发式增长。在音视频领域中,WebRTC可以说是一个绕不开宝库,包括了音视频采集、编解码、传输、渲染的全过程。本文主要记录下在Linux平台上编译WebRTC Linux和Android...

吴尼玛阅读 3.3k评论 2

18 声望
5 粉丝
宣传栏