Android:NavigationView 导航抽屉

NavigationView是一种标准的应用导航菜单,菜单栏的内容可以来自菜单栏资源文件。

NavigationView最典型的应用场景是放到DrawerLayout里使用。

API:https://developer.android.com/reference/android/support/design/widget/NavigationView.html

 

1. build.gradle里面添加 compile 'com.android.support:design:24.0.0',版本号需要跟API版本号相同;

apply plugin: 'com.android.application'

android {
    compileSdkVersion 24
    buildToolsVersion "24.0.0"
    defaultConfig {
        applicationId "com.media.customplayer"
        minSdkVersion 18
        targetSdkVersion 24
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
    productFlavors {
    }
}

dependencies {
    compile fileTree(include: ['*.jar'], dir: 'libs')
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:24.0.0'
    compile 'com.android.support:design:24.0.0'
}
View Code

2. 布局配置文件添加指向res-auto的域名 xmlns:app="http://schemas.android.com/apk/res-auto" 

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/palyer_drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:context=".PlayerActivity"
    >
View Code

3. res目录下添加menu目录,在menu下添加菜单栏资源文件

    menu api: http://developer.android.com/guide/topics/resources/menu-resource.html

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <group android:checkableBehavior="single">
        <item
            android:id="@+id/navi_all"
            android:checked="true"
            android:icon="@mipmap/ic_allmusic_black_24dp"
            android:title="@string/drawer_allmusic_title" />
        <item
            android:id="@+id/navi_playlists"
            android:icon="@mipmap/ic_playlist_music_black_24dp"
            android:title="@string/drawer_playlists_title" />
    </group>
</menu>
View Code

4. DrawerLayout下添加NavigationView(至此导航栏可以使用了)

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/palyer_drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:context=".PlayerActivity"
    >

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="200dp"
            android:layout_marginTop="200dp"
            android:text="这是主区域"/>

    </RelativeLayout>

    <android.support.design.widget.NavigationView
        android:id="@+id/navi_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        app:menu="@menu/drawer"
        />

</android.support.v4.widget.DrawerLayout>
View Code

5. app:headerLayout接收一个导航菜单栏顶部的布局(可选)

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/palyer_drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:context=".PlayerActivity"
    >

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="200dp"
            android:layout_marginTop="200dp"
            android:text="这是主区域"/>

    </RelativeLayout>

    <android.support.design.widget.NavigationView
        android:id="@+id/navi_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        app:headerLayout="@layout/nav_header"
        app:menu="@menu/drawer"
        />

</android.support.v4.widget.DrawerLayout>
View Code

   nav_header.xml

<?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:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="192dp"
    android:background="?attr/colorPrimaryDark"
    android:padding="16dp"
    app:theme="@style/ThemeOverlay.AppCompat.Dark"
    android:gravity="bottom">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="导航栏Header"
        android:textAppearance="@style/TextAppearance.AppCompat.Body1" />

</LinearLayout>
View Code

6. menu嵌套

   menu支持分组和子标题,但是子标题不支持icon

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <group android:checkableBehavior="single">
        <item
            android:id="@+id/navi_all"
            android:checked="true"
            android:icon="@mipmap/ic_allmusic_black_24dp"
            android:title="@string/drawer_allmusic_title" />
        <item
            android:id="@+id/navi_playlists"
            android:icon="@mipmap/ic_playlist_music_black_24dp"
            android:title="@string/drawer_playlists_title" />

        <item
            android:id="@+id/navi_sub_header"
            android:icon="@mipmap/ic_by_genre"
            android:title="@string/drawer_sub_navi_title">

            <menu>
                <item
                    android:id="@+id/navi_sub_item_1"
                    android:icon="@mipmap/ic_allmusic_black_24dp"
                    android:title="@string/drawer_sub_playlist_title" />
                <item
                    android:id="@+id/navi_sub_item_2"
                    android:icon="@mipmap/ic_allmusic_black_24dp"
                    android:title="@string/drawer_sub_playlist_title" />
            </menu>

        </item>
    </group>
</menu>
View Code

   经过测试,子分组可以放到group里面,可以放到外面

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <group android:checkableBehavior="single">
        <item
            android:id="@+id/navi_all"
            android:checked="true"
            android:icon="@mipmap/ic_allmusic_black_24dp"
            android:title="@string/drawer_allmusic_title" />
        <item
            android:id="@+id/navi_playlists"
            android:icon="@mipmap/ic_playlist_music_black_24dp"
            android:title="@string/drawer_playlists_title" />

        <item
            android:id="@+id/navi_sub_header"
            android:icon="@mipmap/ic_by_genre"
            android:title="@string/drawer_sub_navi_title">

            <menu>
                <item
                    android:id="@+id/navi_sub_item_1"
                    android:icon="@mipmap/ic_allmusic_black_24dp"
                    android:title="@string/drawer_sub_playlist_title" />
                <item
                    android:id="@+id/navi_sub_item_2"
                    android:icon="@mipmap/ic_allmusic_black_24dp"
                    android:title="@string/drawer_sub_playlist_title" />
            </menu>

        </item>
    </group>

    <item
        android:id="@+id/navi_sub_header_bottom"
        android:icon="@mipmap/ic_by_genre"
        android:title="@string/drawer_sub_navi_title">

        <menu>
            <item
                android:id="@+id/navi_sub_item_bottom_1"
                android:icon="@mipmap/ic_allmusic_black_24dp"
                android:title="@string/drawer_sub_playlist_title" />
            <item
                android:id="@+id/navi_sub_item_bottom_2"
                android:icon="@mipmap/ic_allmusic_black_24dp"
                android:title="@string/drawer_sub_playlist_title" />
        </menu>

    </item>
</menu>
View Code

7. 导航菜单项被点击时的回掉:setNavigationItemSelectedListener(OnNavigationItemSelectedListener)

package com.media.customplayer;

import android.support.design.widget.NavigationView;
import android.support.design.widget.NavigationView.OnNavigationItemSelectedListener;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.support.v4.widget.DrawerLayout.DrawerListener;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.MenuItem;
import android.view.View;

public class PlayerActivity extends AppCompatActivity {

    private final String TAG = "PlayerActivity";
    private DrawerLayout mPlayerDrawer;
    private NavigationView mNaviView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_player);

        mPlayerDrawer = (DrawerLayout) findViewById(R.id.palyer_drawer_layout);
        mPlayerDrawer.addDrawerListener(drawerListener);

        mNaviView = (NavigationView) findViewById(R.id.navi_view);
        mNaviView.setNavigationItemSelectedListener(naviItemSelectedListener);
    }

    private DrawerListener drawerListener = new DrawerLayout.DrawerListener() {
        @Override
        public void onDrawerSlide(View drawerView, float slideOffset) {
            Log.v(TAG, "onDrawerSlide: slideOffset = " + slideOffset);
        }

        @Override
        public void onDrawerOpened(View drawerView) {
            Log.v(TAG, "onDrawerOpened");
        }

        @Override
        public void onDrawerClosed(View drawerView) {
            Log.v(TAG, "onDrawerClosed");
        }

        @Override
        public void onDrawerStateChanged(int newState) {
            Log.v(TAG, "onDrawerStateChanged: newState = " + newState);
        }
    };

    private OnNavigationItemSelectedListener naviItemSelectedListener = new OnNavigationItemSelectedListener() {
        @Override
        public boolean onNavigationItemSelected(MenuItem item) {
            switch (item.getItemId()) {
                case R.id.navi_all:
                    Log.v(TAG, "播放所有音乐");
                    break;
                case R.id.navi_playlists:
                    Log.v(TAG, "播放音乐列表");
                    break;
                default:
                    Log.v(TAG, "点击按钮: " + item.getItemId());
            }

            item.setChecked(true);
            mPlayerDrawer.closeDrawer(GravityCompat.START, true);
            return true;
        }
    };

}
View Code

但是问题来了,分组的菜单项虽然可以触发此事件,但是子分组的菜单项此时都变成多选了

经过测试发现,子分组menu下先嵌套group(

<item>
<menu>
<group android:checkableBehavior="single">
<item />
<item />
</group>
</menu>
</item>

),再嵌套item即可解决。

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <group android:checkableBehavior="single">
        <item
            android:id="@+id/navi_all"
            android:checked="true"
            android:icon="@mipmap/ic_allmusic_black_24dp"
            android:title="@string/drawer_allmusic_title" />
        <item
            android:id="@+id/navi_playlists"
            android:icon="@mipmap/ic_playlist_music_black_24dp"
            android:title="@string/drawer_playlists_title" />

        <item
            android:id="@+id/navi_sub_header"
            android:icon="@mipmap/ic_by_genre"
            android:title="@string/drawer_sub_navi_title">

            <menu>
                <group android:checkableBehavior="single">
                    <item
                        android:id="@+id/navi_sub_item_1"
                        android:icon="@mipmap/ic_allmusic_black_24dp"
                        android:title="@string/drawer_sub_playlist_title" />
                    <item
                        android:id="@+id/navi_sub_item_2"
                        android:icon="@mipmap/ic_allmusic_black_24dp"
                        android:title="@string/drawer_sub_playlist_title" />
                </group>
            </menu>

        </item>
    </group>

    <item
        android:id="@+id/navi_sub_header_bottom"
        android:icon="@mipmap/ic_by_genre"
        android:title="@string/drawer_sub_navi_title">

        <menu>
            <group android:checkableBehavior="single">
                <item
                    android:id="@+id/navi_sub_item_bottom_1"
                    android:icon="@mipmap/ic_allmusic_black_24dp"
                    android:title="@string/drawer_sub_playlist_title" />
                <item
                    android:id="@+id/navi_sub_item_bottom_2"
                    android:icon="@mipmap/ic_allmusic_black_24dp"
                    android:title="@string/drawer_sub_playlist_title" />
            </group>
        </menu>

    </item>
</menu>
View Code

还需要注意的时,选中的菜单项,还是可以触发selected事件的。

 

 

 

  

 

posted on 2016-07-13 15:29  alvin.zhang  阅读(994)  评论(0编辑  收藏  举报

导航