一、简介
DrawerLayout可以轻松的实现抽屉效果、在DrawerLayout中,第一个子View必须是显示内容的view,第二个view是抽屉view,设置属性layout_gravity=”left|right”,表示是从左边滑出还是右边滑出。
NavigationView是Android M中提出一个新的MD风格的组件,它将自己一分为二,上面显示一个通用的布局,下面显示一组菜单。与DrawerLayout一起使用可以实现通用的侧滑菜单。
简单来说就是:
DrawerLayout:实现侧滑菜单的基础。
NavigationView:作为侧滑菜单布局的一种实现方式。
二、NavigationView占满全屏
DrawerLayout有两个子布局
第一个是主界面(使用FrameLayout,宽高都match_parent)
第二个就是侧滑菜单的布局了(使用NavigationView,通过设置layout_gravity为left 或是right 来确定菜单摆放的位置)。
打开抽屉: DrawerLayout .openDrawer();
关闭抽屉:DrawerLayout.closeDrawer( );
1、布局
目录结构:
NavigationView通常放置在DrawerLayout内部。
<?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/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:openDrawer="start">
<!--第一个,显示的布局-->
<include
layout="@layout/app_bar_main"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<!--第二个,不显示的抽屉布局-->
<!-- 菜单布局NavigationView headerLayout设置HeaderView menu设置菜单 -->
<android.support.design.widget.NavigationView
android:id="@+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:headerLayout="@layout/nav_header_main"
app:menu="@menu/activity_main_drawer" />
</android.support.v4.widget.DrawerLayout>
NavigationView有两个app属性,分别为app:headerLayout和app:menu,headerLayout用于显示头部的布局(可选),menu用于建立MenuItem选项的菜单。
其中:
android:fitsSystemWindows的值用于设置状态栏透明化与否。
android:layout_gravity可设置抽屉,也就是NavigationView从左边或是右边打开。
app:menu用于设置菜单内容的xml布局。
app:headerLayout用于设置NavigationView的HeaderView的xml布局文件。
app_bar_main布局文件为:
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout 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:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
>
<android.support.design.widget.AppBarLayout
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="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="@style/AppTheme.PopupOverlay" />
</android.support.design.widget.AppBarLayout>
<!--引入content_main布局-->
<include layout="@layout/content_main" />
</android.support.design.widget.CoordinatorLayout>
content_main布局文件为:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:showIn="@layout/app_bar_main">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!" />
<Button
android:id="@+id/snackbar"
android:layout_below="@id/textView"
android:text="点我吧"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</RelativeLayout>
2、编写NavigationView中的menu的xml文件
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<group android:checkableBehavior="none">
<item
android:id="@+id/nav_me"
android:title="我"
android:icon="@mipmap/ic_mine_gray_24"/>
<item
android:id="@+id/nav_friend"
android:title="好友"
android:icon="@mipmap/ic_friends_gray_24"/>
<item
android:id="@+id/nav_notification"
android:title="通知"
android:icon="@mipmap/ic_notification_gray_24"/>
<item
android:id="@+id/nav_message"
android:title="私信"
android:icon="@mipmap/ic_messages_gray_24"
/>
</group>
<group android:checkableBehavior="none"
android:id="@+id/group_manage">
<item
android:id="@+id/nav_manage"
android:title="应用管理"
android:icon="@mipmap/ic_app_management_gray_24"/>
</group>
<group
android:checkableBehavior="none"
android:id="@+id/group_settings">
<item android:id="@+id/nav_theme"
android:title="主题风格"/>
<item android:id="@+id/nav_night"
android:title="夜间模式"/>
<item android:id="@+id/nav_setting"
android:title="设置"/>
<item android:id="@+id/nav_suggestion"
android:title="意见反馈"/>
<item android:id="@+id/nav_about"
android:title="关于"/>
</group>
</menu>
menu可以分组,group的android:checkableBehavior属性设置为single可以设置该组为单选
Activity主题必须设置先这两个属性
<style name="AppTheme.NoActionBar">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
</style>
未设置Activity主题会爆出错误信息:
vCaused by: java.lang.IllegalStateException: This Activity
already has an action bar supplied by the window decor.
Do not request Window.FEATURE_SUPPORT_ACTION_BAR
and set windowActionBar to false in your theme to use a Toolbar instead.
在AndroidManifest.xml中设置主题为android:theme="@style/AppTheme.NoActionBar"
3、实现onNavigationItemSelected接口来处理抽屉菜单项的选中事件。
这里用了ButterKnife所以要加入依赖:
compile 'com.jakewharton:butterknife:7.0.1'
代码如下:
package com.example.demo2;
import android.content.Intent;
import android.support.annotation.NonNull;
import android.support.design.widget.NavigationView;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.Toolbar;
import android.text.TextUtils;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import butterknife.ButterKnife;
import butterknife.OnClick;
public class MainActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener, View.OnClickListener{
private TextView mTextView;
private ImageView mImageView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.setDrawerListener(toggle);
toggle.syncState();
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
mTextView = (TextView) findViewById(R.id.textView);
mImageView = (ImageView) navigationView.getHeaderView(0).findViewById(R.id.ivAvatar);
mImageView.setOnClickListener(this);
ButterKnife.bind(this);
}
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
public void onClick(View view) {
if(view.getId()==R.id.ivAvatar){
Toast.makeText(getApplicationContext(), "点击了头像", Toast.LENGTH_SHORT).show();
//Intent intent = new Intent(this,LoginActivity.class);
//startActivity(intent);
}
}
@OnClick(R.id.snackbar)
void goToSnackbar(){
//startActivity(new Intent(this,SnackBarActivity.class));
Toast.makeText(getApplicationContext(), "你点击了我!!!", Toast.LENGTH_SHORT).show();
}
@SuppressWarnings("StatementWithEmptyBody")
@Override
public boolean onNavigationItemSelected(MenuItem item) {
int id = item.getItemId();
String string = null;
switch (id){
case R.id.nav_me:
string = "我";
break;
case R.id.nav_about:
string = "关于";
break;
case R.id.nav_friend:
string = "好友";
break;
case R.id.nav_manage:
string = "通知";
break;
case R.id.nav_message:
string = "私信";
break;
case R.id.nav_night:
string = "夜间模式";
break;
case R.id.nav_notification:
string = "通知";
break;
case R.id.nav_setting:
string= "设置";
break;
case R.id.nav_suggestion:
string = "意见反馈";
break;
case R.id.nav_theme:
string = "主题风格";
break;
}
if (!TextUtils.isEmpty(string))
mTextView.setText("你点击了"+string);
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
@Override
public void onBackPressed() {
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else {
super.onBackPressed();
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
//右角设置布局
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
效果图:
示例:http://download.youkuaiyun.com/detail/u011781521/9829159
四、NavigationView在Toolbar下方
activity_main.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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="zhj.newtoolbardemo.MainActivity">
<android.support.v7.widget.Toolbar
android:id="@+id/mToolBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
android:elevation="4dp"
android:theme="@style/ThemeOverlay.AppCompat.ActionBar"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
>
</android.support.v7.widget.Toolbar>
<android.support.v4.widget.DrawerLayout
android:id="@+id/drawerLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- 内容部分 -->
<FrameLayout
android:id="@+id/content"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<!-- 左侧侧滑部分 -->
<android.support.design.widget.NavigationView
android:id="@+id/nv_menu_left"
android:layout_width="240dp"
android:layout_height="match_parent"
android:layout_gravity="left"
app:headerLayout="@layout/header"
app:menu="@menu/menu_drawer"/>
</android.support.v4.widget.DrawerLayout>
</LinearLayout>
头文件header.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/colorPrimary"
android:orientation="vertical">
<ImageView
android:id="@+id/header"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:layout_marginTop="15dp"
android:layout_marginBottom="15dp"
android:background="@mipmap/ic_launcher"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/header"
android:layout_centerHorizontal="true"
android:layout_marginBottom="15dp"
android:layout_marginTop="10dp"
android:text="fendo"
android:textColor="@android:color/white"
android:textSize="16sp"/>
</RelativeLayout>
菜单选项文件:
1.menu_drawer.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<group>
<item
android:id="@+id/navigation_item1"
android:checkable="true"
android:checked="true"
android:icon="@mipmap/ic_launcher"
android:title="选项一"/>
<item
android:id="@+id/navigation_item2"
android:checkable="true"
android:icon="@mipmap/ic_launcher"
android:title="选项二"/>
<item
android:id="@+id/navigation_item3"
android:checkable="true"
android:icon="@mipmap/ic_launcher"
android:title="选项三"/>
</group>
<item
android:id="@+id/navigation_sub"
android:title="设置">
<menu>
<item
android:id="@+id/navigation_sub_item1"
android:checkable="true"
android:icon="@mipmap/ic_launcher"
android:title="简介"/>
<item
android:id="@+id/navigation_sub_item2"
android:checkable="true"
android:icon="@mipmap/ic_launcher"
android:title="详情"/>
<item
android:id="@+id/navigation_sub_item3"
android:checkable="true"
android:icon="@mipmap/ic_launcher"
android:title="更多"/>
</menu>
</item>
</menu>
2.menu_main.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
>
<item android:id="@+id/action_1"
android:title="其他"
android:orderInCategory="80"
android:icon="@mipmap/ic_launcher"
app:showAsAction="never" />
<item android:id="@+id/action_tip"
android:title="提醒"
android:orderInCategory="90"
android:icon="@mipmap/ic_launcher"
app:showAsAction="never" />
<item android:id="@+id/action_menu"
android:title="设置"
android:orderInCategory="90"
android:icon="@mipmap/ic_launcher"
app:showAsAction="never" />
</menu>
Main文件:
package zhj.newtoolbardemo;
import android.os.Bundle;
import android.support.design.widget.NavigationView;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.Window;
import android.widget.ImageView;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
private DrawerLayout mDrawerLayout;
private Toolbar mToolBar;
private ActionBarDrawerToggle mDrawerToggle;
private NavigationView nv_menu_left;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
supportRequestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
mToolBar = (Toolbar) findViewById(R.id.mToolBar);
nv_menu_left= (NavigationView) findViewById(R.id.nv_menu_left);
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawerLayout);
View headerView = nv_menu_left.getHeaderView(0);
ImageView iv= (ImageView) headerView.findViewById(R.id.header);
mToolBar.setTitle("标题"); //设置主标题
setSupportActionBar(mToolBar); //设置actionbar
getSupportActionBar().setHomeButtonEnabled(true); //设置返回键可用
getSupportActionBar().setDisplayHomeAsUpEnabled(true); //创建返回键,并实现打开关/闭监听
mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, mToolBar, R.string.app_name, R.string.app_name){
@Override
public void onDrawerOpened(View drawerView) {
super.onDrawerOpened(drawerView);
}
@Override
public void onDrawerClosed(View drawerView) {
super.onDrawerClosed(drawerView);
}
};
mDrawerToggle.syncState(); //初始化状态
mDrawerLayout.addDrawerListener(mDrawerToggle); //将DrawerLayout与DrawerToggle绑定
//为头像设置点击事件
iv.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(getApplicationContext(), "你点击了头像", Toast.LENGTH_SHORT).show();
}
});
//设置导航栏NavigationView的点击事件
nv_menu_left.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(MenuItem item) {
Toast.makeText(getApplicationContext(), item.getItemId(), Toast.LENGTH_SHORT).show();
switch (item.getItemId()) {
case R.id.navigation_item1:
mToolBar.setTitle("选项一");
break;
case R.id.navigation_item2:
mToolBar.setTitle("选项二");
break;
case R.id.navigation_item3:
mToolBar.setTitle("选项三");
break;
case R.id.navigation_sub_item1:
mToolBar.setTitle("简介");
break;
case R.id.navigation_sub_item2:
mToolBar.setTitle("详情");
break;
case R.id.navigation_sub_item3:
mToolBar.setTitle("更多");
break;
}
//将选中设为点击状态
item.setChecked(true);
//关闭抽屉
mDrawerLayout.closeDrawers();
return true;
}
});
}
// 菜单的点击回调
private Toolbar.OnMenuItemClickListener onMenuItemClick = new Toolbar.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem menuItem) {
String msg = "";
switch (menuItem.getItemId()) {
case R.id.action_1:
msg += "点击其他1";
break;
case R.id.action_tip:
msg += "点击提醒";
break;
case R.id.action_menu:
msg += "点击设置";
break;
}
if (!msg.equals("")) {
Toast.makeText(MainActivity.this, msg, Toast.LENGTH_SHORT).show();
}
return true;
}
};
//设置右上角的填充菜单
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
}
效果如下: