Android Material Design Library 推出了很長時間,越來越多的APP使用了符合Library 包的控件,DrawerLayout絕對是熱門之一,Material Design定義了一個抽屜導航應該有何種外觀和感受,統一了側滑菜單和樣式。在Android原生手機上對DrawerLayout+NavigationView更是使用到了極致,如Gmail,Google Map
關于DrawerLayout和NavigationView的使用介紹博客有很多,這里主要是實現一些使用上的介紹,如讓NavigationView在Toolbar下方,不顯示Toolbar左側按鈕等。
下面開始看下DrawerLayout的如何使用,首先在build.gradle中引入Design包
compile ‘com.android.support:design:24.2.1’
新建一個Activity,這里我們選擇使用Android Studio提供的模板,選擇NavgationDrawer Activity
查看下界面的xml文件
可以看到我們的最外層是DrawerLayout,包含了兩個內容:include為顯示內容區域,NavigationView為側邊抽屜欄。
NavigationView有兩個app屬性,分別為app:headerLayout和app:menu,eaderLayout用于顯示頭部的布局(可選),menu用于建立MenuItem選項的菜單。
headerLayout就是正常的layout布局文件,我們查看下menu.xml
<?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/nav_camera" android:icon="@drawable/ic_menu_camera" android:title="Import"/> <item android:id="@+id/nav_gallery" android:icon="@drawable/ic_menu_gallery" android:title="Gallery"/> <item android:id="@+id/nav_slideshow" android:icon="@drawable/ic_menu_slideshow" android:title="Slideshow"/> <item android:id="@+id/nav_manage" android:icon="@drawable/ic_menu_manage" android:title="Tools"/> </group> <item android:title="Communicate"> <menu> <item android:id="@+id/nav_share" android:icon="@drawable/ic_menu_share" android:title="Share"/> <item android:id="@+id/nav_send" android:icon="@drawable/ic_menu_send" android:title="Send"/> </menu> </item></menu>menu可以分組,group的android:checkableBehavior屬性設置為single可以設置該組為單選
Activity主題必須設置先這兩個屬性
<style name="A未設置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.設置主題為android:theme=”@style/AppTheme.NoActionBar”
最后java代碼
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);效果圖: 
NavigationView監聽通過navigationView.setNavigationItemSelectedListener(this)方法去監聽menu的點擊事件
@Sup每次點擊一個Menu關閉DrawerLayout,方法為drawer.closeDrawer(GravityCompat.START);通過onBackPressed方法,當點擊返回按鈕的時候,如果DrawerLayout是打開狀態則關閉
@Override public void onBackPressed() { DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout); if (drawer.isDrawerOpen(GravityCompat.START)) { drawer.closeDrawer(GravityCompat.START); } else { super.onBackPressed(); } }大多數的APP都是使用NavigationView都是全屏的,當我們想讓NavigationView在Toolbar下方的時候應該怎么做呢 xml布局如下圖,DrawerLayout在Toolbar的下方
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/sample_main_layout" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:background="?attr/colorPrimary" app:theme="@style/ThemeOverlay.AppCompat.Dark" /> <android.support.v4.widget.DrawerLayout android:id="@+id/drawer_layout" android:layout_width="match_parent" android:layout_height="match_parent"> <FrameLayout android:id="@+id/container" android:layout_width="match_parent" android:layout_height="match_parent" > <TextView android:padding="16dp" android:text="NavigationView在Toolbar下方" android:gravity="center" android:layout_width="match_parent" android:layout_height="match_parent" /> </FrameLayout> <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_drawer_layout_one" app:menu="@menu/activity_drawer_layout_one_drawer"/> </android.support.v4.widget.DrawerLayout></LinearLayout>效果如圖: 
上圖可以看到我們點擊Home旋轉開關按鈕,顯示和隱藏了側滑菜單。那么如果我們想要不通過按鈕點擊,只能右劃拉出菜單需要怎么做呢。 我們先看下帶Home旋轉開關按鈕的代碼是如何寫的:
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);//這是帶Home旋轉開關按鈕ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);drawer.setDrawerListener(toggle);toggle.syncState();這個Home旋轉開關按鈕實際上是通過ActionBarDrawerToggle代碼綁定到toolbar上的,ActionBarDrawerToggle是和DrawerLayout搭配使用的,它可以改變android.R.id.home返回圖標,監聽drawer的顯示和隱藏。ActionBarDrawerToggle的syncState()方法會和Toolbar關聯,將圖標放入到Toolbar上。 進入ActionBarDrawerToggle構造器可以看到一個不傳Toolbar參數的構造器
public ActionBarDrawerToggle(Activity activity, DrawerLayout drawerLayout, @StringRes int openDrawerContentDescRes, @StringRes int closeDrawerContentDescRes) { this(activity, null, drawerLayout, null, openDrawerContentDescRes, closeDrawerContentDescRes);}那么不帶Home旋轉開關按鈕的代碼如下
//這是不帶Home旋轉開關按鈕ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, drawer, R.string.navigation_drawer_open, R.string.navigation_drawer_close);當然我們把上面帶Home旋轉開關按鈕的代碼刪除也是可以的。
效果如圖: 
APP實際開發中往往不能完全按照Materialdesign的規則來,如網易云音樂的側滑,底部還有兩個按鈕。這時候我們可以通過+其他布局來實現特殊的側滑布局。
我們可以參考鴻楊大神的博客 Android 自己實現 NavigationView [Design Support Library(1)]
我們自己實現個簡單的,DrawerLayout包裹了一個FrameLayout和一個RelativeLayout,FrameLayout是我們的顯示內容區域,RelativeLayout是我們的側邊欄布局。
<android.support.v4.widget.DrawerLayout android:id="@+id/drawer_layout" 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" tools:openDrawer="start"> <FrameLayout android:id="@+id/container" android:layout_width="match_parent" android:layout_height="match_parent"> <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"/> <TextView android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:padding="16dp" android:text="@string/title_activity_drawer_layout_other"/> </FrameLayout> <RelativeLayout android:id="@+id/nav_view" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="start" android:background="@android:color/white" android:fitsSystemWindows="true"> <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:text="這是頂部按鈕"/> <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_centerInParent="true" android:text="這是中間的按鈕"/> <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:text="這是底部按鈕"/> </RelativeLayout></android.support.v4.widget.DrawerLayout>如果需要監聽DrawerLayout的側滑狀態監聽,那么代碼如下:
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout); /** * 也可以使用DrawerListener的子類SimpleDrawerListener, * 或者是ActionBarDrawerToggle這個子類 */ mDrawerLayout.setDrawerListener(new DrawerLayout.SimpleDrawerListener() { @Override public void onDrawerClosed(View drawerView) { super.onDrawerClosed(drawerView); } @Override public void onDrawerOpened(View drawerView) { super.onDrawerOpened(drawerView); } });效果圖如下:

最后上github地址
https://github.com/itdais/MaterialDesignDing
新聞熱點
疑難解答