Material Design之NavigationView的用

作者: 流水潺湲 | 来源:发表于2017-05-22 14:19 被阅读416次

    Android自带抽屉布局及NavigationView的使用

    抽屉布局

    导航菜单的制作方式多种多样,网上也有各种炫酷效果的具体实现方式,那么今天我主要是想来说说Google在Android5.0之后推出的NavigationView的具体使用方式。

    DrawerLayout

    DrawerLayout,在根布局之后又主要分为三大块,第一块就是我们主界面的内容,第二块是左边拉出来的布局,第三块是右边拉出来的布局(不需要右边侧拉就不用写,这样的话整个布局就只分为两大块),那么系统怎么知道我们这个布局是主布局还是侧拉菜单的布局?请注意左边侧拉菜单布局android:layout_gravity="left"这个属性和右边菜单布局的android:layout_gravity="right"这个属性,哈哈,这下应该明白了吧,系统通过layout_gravity属性的值来判断这个布局是左边菜单的布局还是右边菜单的布局,如果没有这个属性,那不用说,肯定是主界面的布局。

    1.NavigationView是什么

    long long ago,我们做抽屉菜单的时候,左边滑出来的那一部分的布局都是由我们自己来定义的,自己写的话,花点时间也能做出来好看的侧拉菜单,但总是要耗费时间,于是Google在5.0之后推出了NavitationView,就是我们左边滑出来的那个菜单。这个菜单整体上分为两部分,上面一部分叫做HeaderLayout,下面的那些点击项都是menu,这样的效果如果我们要自己写肯定也能写出来,但是没有必要,既然Google提供了这个控件,那我们就来看看这个控件要怎么用吧。

    2.NavigationView怎么用

    和普通的侧拉菜单制作方式一样,首先所有的东西还是都放在一个DrawerLayout中(如果你对DrawerLayout的使用还不熟悉,请参考这篇文章使用DrawerLayout实现侧拉菜单),只不过这次我们把左边滑出菜单的布局用一个NavigationView来代替,代码如下:

    <?xml version="1.0" encoding="utf-8"?>
    
    <FrameLayout 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:fitsSystemWindows="true">
    
        <android.support.v4.widget.DrawerLayout
            android:id="@+id/drawer_layout"
            android:layout_width="match_parent"
            android:layout_height="match_parent">
    
            <android.support.design.widget.CoordinatorLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent">
    
    
                <android.support.design.widget.AppBarLayout
                    android:id="@+id/appbar_layout"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:theme="@style/AppTheme.AppBarOverlay">
    
                    <android.support.v7.widget.Toolbar
                        android:id="@+id/toolbar"
                        android:layout_width="match_parent"
                        android:layout_height="?actionBarSize"
                        android:background="?attr/colorPrimary"
                        app:popupTheme="@style/AppTheme.PopupOverlay" />
    
    
                </android.support.design.widget.AppBarLayout>
                <!--内容 -可切换Fragment-->
                <LinearLayout
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:orientation="vertical"
                    app:layout_behavior="@string/appbar_scrolling_view_behavior">
    
                    <TextView
                        android:id="@+id/message"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content" />
    
                    <Button
                        android:id="@+id/nextButton"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_gravity="center_horizontal"
                        android:text="测试" />
    
    
                </LinearLayout>
            </android.support.design.widget.CoordinatorLayout>
    
            <!--左侧导航菜单-->
            <android.support.design.widget.NavigationView
                android:id="@+id/navigation_view"
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:layout_gravity="start"
                android:background="@color/windowBackground"
                app:headerLayout="@layout/navigation_header"
                app:menu="@menu/drawer" />
        </android.support.v4.widget.DrawerLayout>
    </FrameLayout>
    

    分别解释一下这里边几个属性的含义:

    • 1.Android:layout_gravity="left"属性表示该View是左边的滑出菜单,这个属性的含义不用多说,这是DrawerLayout使用方式中的知识点。
      NavigationView需要设置 android:layout_gravity="start"
    • 2.app:headerLayout="@layout/header_layout"表示引用一个头布局文件,这个头就是我们在上面看到的那个背景图片,包括背景图片上面的显示用户名的控件等等。
    • 3.app:menu="@menu/main"表示引用一个menu作为下面的点击项

    头布局文件:

    <?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:id="@+id/ll_navigation_header"
        android:layout_width="match_parent"
        android:layout_height="192dp"
        android:background="?attr/colorPrimary"
        android:gravity="center"
        android:orientation="vertical"
        android:padding="16dp"
        android:theme="@style/ThemeOverlay.AppCompat.Dark">
    
    
        <ImageView
            android:id="@+id/profile_image"
            android:layout_width="72dp"
            android:layout_height="72dp"
            android:layout_marginTop="20dp"
            android:src="@mipmap/logo"
             />
    
    
        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="10dp"
            android:gravity="center"
            android:text="HSY"
            android:textColor="#ffffff"
            android:textAppearance="@style/TextAppearance.AppCompat.Body1"
            android:textSize="18sp" />
    
    </LinearLayout>
    

    再来看看menu文件:

    <?xml version="1.0" encoding="utf-8"?>
    <menu xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools">
    
        <group android:checkableBehavior="single">
    
            <item
                android:checked="true"
                android:id="@+id/navigation_item_home"
                android:icon="@drawable/iconfont_home"
                android:title="首页" />
            <item
                android:id="@+id/navigation_item_ganhuo"
    
                android:icon="@drawable/iconfont_source"
                android:title="干货" />
            <item
                android:id="@+id/navigation_item_blog"
                android:icon="@drawable/iconfont_blog"
                android:title="我的博客" />
            <item
                android:id="@+id/navigation_item_custom_view"
                android:icon="@drawable/iconfont_custom_view"
                android:title="自定义View" />
            <item
                android:id="@+id/navigation_item_snackbar"
                android:icon="@drawable/iconfont_custom_view"
                android:title="Snackbar演示" />
    
            <item android:title="其他">
                <menu>
                    <item
                        android:id="@+id/navigation_item_switch_theme"
                        android:checkable="true"
                        android:icon="@drawable/iconfont_skin"
                        android:title="主题换肤" />
    
                    <item
                        android:id="@+id/navigation_item_about"
                        android:checkable="true"
                        android:icon="@drawable/iconfont_about"
                        android:title="关于" />
                </menu>
            </item>
        </group>
    
    </menu>
    

    注意:


    1.在布局文件中添加app:itemIconTint="@color/blue"属性,表示设置图片的颜色全都为蓝色


    2.第一种解决方案会让所有的图片以一种颜色来显示,如果我想让图片就是显示他本身的颜色该怎么办呢?在Java代码中调用如下方法:

    NavigationView navigationView = (NavigationView) findViewById(R.id.navigation_view);  
            navigationView.setItemIconTintList(null);  
    

    还有下面两个常用的API:

    1.app:itemBackground="@color/colorAccent"设置每一个item的背景颜色
    2.app:itemTextColor=""设置item的背景颜色
    
    

    3.如果我想在NavigationView的item之间添加上一条分隔线呢?很简单,只需要在menu中将相应的item放到一个group中,并给该group取一个id即可,代码如下:

    <?xml version="1.0" encoding="utf-8"?>  
    <menu xmlns:android="http://schemas.android.com/apk/res/android">  
        <group android:id="@+id/g1">  
            <item  
                android:id="@+id/favorite"  
                android:icon="@mipmap/ic_launcher"  
                android:title="收藏"/>  
            <item  
                android:id="@+id/wallet"  
                android:icon="@mipmap/ic_launcher"  
                android:title="钱包"/>  
        </group>  
        <group android:id="@+id/g2">  
            <item  
                android:id="@+id/photo"  
                android:icon="@mipmap/ic_launcher"  
                android:title="相册"/>  
        </group>  
        <item  
            android:id="@+id/file"  
            android:icon="@mipmap/ic_launcher"  
            android:title="文件"/>  
    </menu>  
    

    4.隐藏某个菜单列表项

    公司项目会根据你是否是管理员,来控制某个菜单列表项的显示和隐藏,因此就出现了这个问题。
    原以为比较麻烦,后来搜了下,也比较简单地解决了,直接上代码:

    MenuItem menuItem = navigationView.getMenu().findItem(R.id.some_menu_item);
    menuItem.setVisible(false); // true 为显示,false 为隐藏
    

    5. 使用 NavigationView 时透明状态栏的处理

    Android App 沉浸式状态栏解决方案

    NavigationView中的事件监听

    1.头部点击事件

    处理头部点击事件,我们需要先获得到头部控件,在Java代码中我们可以通过下面的方式获得头部控件,

    //获取头布局文件  
            View headerView = navigationView.getHeaderView(0);  
    

    然后通过调用headerView中的findViewById方法来查找到头部的控件,设置点击事件即可。

    2.item点击事件

    navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {  
        @Override  
        public boolean onNavigationItemSelected(MenuItem item) {  
            //在这里处理item的点击事件  
            return true;  
        }  
    });  
    

    官方文档:

    通过查看谷歌官方开发文档我们还可以发现几个方法https://developer.android.com/reference/android/support/design/widget/NavigationView.html

    源码路径在NoFragmentDemo里面:
    Demo :https://github.com/huangshuyuan/NoFragmentDemo/

    相关文章

      网友评论

        本文标题:Material Design之NavigationView的用

        本文链接:https://www.haomeiwen.com/subject/lxbbxxtx.html