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'
}

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"
>

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>

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>

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>

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>

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>

经过测试,子分组可以放到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>

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;
}
}; }

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

经过测试发现,子分组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>

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

Android:NavigationView 导航抽屉的更多相关文章

  1. 第三十二篇-NavigationView导航抽屉的使用

    效果图: 导航抽屉所用到的布局是DrawerLayout,可以在里面添加一个线性布局和TextView组件,TextView组件的文本信息就是"主页面".然后和线性布局平行添加一个 ...

  2. Android Design Support Library(二)用NavigationView实现抽屉菜单界面

    NavigationView在MD设计中非常重要,之前Google也提出了使用DrawerLayout来实现导航抽屉.这次,在Android Design Support Library中,Googl ...

  3. Android开发之Navigationdrawer导航抽屉功能的实现(源码分享)

    导航抽屉(navigationdrawer)是一个从屏幕左边滑入的面板,用于显示应用的主要导航项目.用户能够通过在屏幕左边缘滑入或者触摸操作栏的应用图标打开导航抽屉. 导航抽屉覆盖在内容之上,但不覆盖 ...

  4. Android导航抽屉-Navigation Drawer

    Google今年七月份的时候更新了他们的Google+应用,采用了新的导航方式并抛弃了navigationdrawer.一时之间,又引发了一系列关于NavigationDrawer利弊的讨论,不过对于 ...

  5. Navigation Drawer(导航抽屉)

    目录(?)[-] 创建一个导航抽屉 创建抽屉布局 初始化抽屉列表 处理导航项选点击事件 监听导航抽屉打开和关闭事件 点击应用图标来打开和关闭导航抽屉 创建一个导航抽屉 导航抽屉是一个位于屏幕左侧边缘用 ...

  6. 【转】Navigation Drawer(导航抽屉)

    创建一个导航抽屉 创建抽屉布局 初始化抽屉列表 处理导航项选点击事件 监听导航抽屉打开和关闭事件 点击应用图标来打开和关闭导航抽屉   创建一个导航抽屉 导航抽屉是一个位于屏幕左侧边缘用来显示应用程序 ...

  7. Android底部导航栏——FrameLayout + RadioGroup

    原创文章,转载请注明出处http://www.cnblogs.com/baipengzhan/p/6285881.html Android底部导航栏有多种实现方式,本文详细介绍FrameLayout ...

  8. Android底部导航栏创建——ViewPager + RadioGroup

    原创文章,引用请注明出处:http://www.cnblogs.com/baipengzhan/p/6270201.html Android底部导航栏有多种实现方式,本文详解其中的ViewPager ...

  9. Android底部导航栏

    Android底部导航栏 今天简单写了一个底部导航栏,封装了一个库,用法比较简单 效果图 Github地址:https://github.com/kongqw/KqwBottomNavigation ...

随机推荐

  1. 第二部分 条件控制执行语句、循环语句、switch语句、跳转语句和其它语句

    条件控制执行语句: if语句 if....else....语句 循环语句: while语句 do....while语句 for语句 switch语句: 跳转语句: break; continue; r ...

  2. Linux笔记(六) - 压缩解压命令

    (1)压缩文件( gz):gzip-d 解压只能压缩文件,不保留原文件例:gzip a.txt(2)解压文件( gz):gunzip 例:gunzip a.txt.gz(3)打包目录(tar):tar ...

  3. bootstropt-table 大量字段整体表单上传之时间处理

    js 中用$('#addUserForm').serialize(),//获取表单中所有数据 传送到前台 (controller) $.ajax({ type : "POST", ...

  4. 数据流程redux学习(一)

    思考题: react+redux开发这么一个原型,要怎么开发? 整个redux流程的逻辑非常清晰,数据流是单向循环的,就像一个生产的流水线: store(存放状态) -> Container(显 ...

  5. iOS 获取公历、农历日期的年月日

    iOS 获取公历.农历日期的年月日 介绍三种方法获取 Date (NSDate) 的年月日. 用 date 表示当前日期.测试日期为公历 2017 年 2 月 5 日,农历丁酉年,鸡年,正月初九. l ...

  6. 免越狱tweak应用逆向开发

    对于已越狱的设备,系统默认安装了mobilesubstrate动态库,提供一个系统级的入侵管道,所有的tweak都可以依赖它来进行开发.而对于没有越狱的手机,我们需要向目标app注入libsubstr ...

  7. .Net程序员学用Oracle系列(13):合并语句(MERGE)

    - 1.[**语法说明**](#segment1) - 1.1.[UPDATE 和 INSERT 可以只出现一个](#point11) - 1.2.[UPDATE 后面还可以再跟 WHERE](#po ...

  8. mybatis入门-动态sql

    什么是动态sql 判断的动态sql mybatis核心就是对sql语句进行灵活操作,通过表达式进行判断,对sql进行灵活拼接.组装. 现有需求如下:需要查询用户,输入的是用户类,如果用户的性别类不为空 ...

  9. swift 2.0 与 OC 相比较,标签栏和导航栏书写的差别

    下面是swift书写的时候的两个方法,其实这里不是教大家怎么样写的这个问题,我是想通过这两个不同语言的进行的一个比较,向大家找他们之间“想法”上的一些相同点,这样子我们学习swift的时候,就可以更加 ...

  10. Python学习--21 电子邮件

    发送邮件 SMTP是发送邮件的协议,Python内置对SMTP的支持,可以发送纯文本邮件.HTML邮件以及带附件的邮件. Python对SMTP支持有smtplib和email两个模块,email负责 ...