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. saiku的源码包Bulid常见问题和jar包

    最近在做kylin+mondrian+saiku的二次开发的时候,Bulid saiku的源码出现了很多问题,基本上一大部分问题jar找不到问题,很多jar国内网站都找不到.这时候只有手动下载然后注册 ...

  2. jmeter线程组配置

    线程组配置 线程组相当于有多个用户,同时去执行相同的一批次任务.每个线程之间都是隔离的,互不影响的.一个线程的执行过程中,操作的变量,不会影响其他线程的变量值. Delay Thread creati ...

  3. Jcompress: 一款基于huffman编码和最小堆的压缩、解压缩小程序

    前言 最近基于huffman编码和最小堆排序算法实现了一个压缩.解压缩的小程序.其源代码已经上传到github上面: Jcompress下载地址 .在本人的github上面有一个叫Utility的re ...

  4. 【thinkphp 5 在nginx 环境下路由无法生效(404 500错误 )的解决方法】

      非常惭愧的说,由于之前一直使用的是windowservice,安装apache来进行服务器布置的,这种方式也是最简单最直接的方式, 但是由于php的服务大多都是linux栈的,咱们也不能落后呀,在 ...

  5. ActionMode 就记这么一点,不能更多了

    话说程序猿都是段子手,看到有的程序猿写文章,前面都会先写一个段子,我这么有幽默感的段子手,也决定效仿一下. "段子." 写完段子,下面开始进入正题. 今天要说的 ActionMod ...

  6. quartz配置时间

    我们需要把log4j的配置文件放入src目录下,启动main类就可以了. Cron Expressions cron的表达式被用来配置CronTrigger实例. cron的表达式是字符串,实际上是由 ...

  7. 阿里云SSD等磁盘挂载方法(详细步骤完整版)

    1,根据提示购买一块,在阿里云管理磁盘的列表"更多"点击,选中"挂载": 2,进入远程实例(远程系统),管理-->存储-->磁盘管理,在右侧看到新挂 ...

  8. Applovin Interview (面经)

    职位:SDE Intern positon 地点: San Jose 轮电面:self introduction what's your interest Concept of "Concu ...

  9. PHP 用session与gd库实现简单验证码生成与验证的类

    验证码是为了防止机器灌水给网站带来污染以及增加服务器负担而出现的.目前大大小小的网站都有验证码.今天自己实现了一个简单的验证码类.说简单是因为没有加一些干扰的弧线等等,只是将文字旋转了一下.当然,因为 ...

  10. Angular2的模块架构浅谈

    引言angular2相比1引入了更完善的模块系统,回忆ng1的应用中通常在页面的html标签或body标签中添加ng-app节点,值为应用的模块名,整个应用都将围绕这个模块来展开,到了ng2,模块概念 ...