android5.0+(NavigationView)
隨著 Google I/O 2015,新的 Android Design Support Library 也出現了。
Android Design Support Library 給開發者帶來了一些重要的 Material Design 組件,并且向下兼容到 Android 2.1, Navigation View 就是其中之一,可用于方便地創建導航抽屜。
效果如下:
因為需要向下兼容,所以以下內容的 Activity 均繼承于 AppCompatActivity ,使用的主題的父主題均為 AppCompat 的主題。
基本步驟
通過 Navigation View 創建導航抽屜首先自然需要引入這個支持包:
compile 'com.android.support:design:22.2.0'
布局文件中加入以下代碼:
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent"> <!-- 需要呈現的內容 --> <android.support.design.widget.NavigationView android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_gravity="start" app:headerLayout="@layout/drawer_header" app:menu="@menu/drawer"/> </android.support.v4.widget.DrawerLayout>
其中 app:headerLayout 用于指定一個任意的布局,作為導航抽屜的頂部,如效果圖中的紫色帶 Username 字樣部分。
而 app:menu 用于指定導航抽屜的菜單項,具體代碼如下:
<menu xmlns:android="http://schemas.android.com/apk/res/android"> <group android:checkableBehavior="single"> <item android:id="@+id/nav_home" android:icon="@drawable/ic_dashboard" android:title="Home" /> <item android:id="@+id/nav_messages" android:icon="@drawable/ic_event" android:title="Messages" /> <item android:id="@+id/nav_friends" android:icon="@drawable/ic_headset" android:title="Friends" /> <item android:id="@+id/nav_discussion" android:icon="@drawable/ic_forum" android:title="Discussion" /> </group> <item android:title="Sub items"> <menu> <item android:icon="@drawable/ic_dashboard" android:title="Sub item 1" /> <item android:icon="@drawable/ic_forum" android:title="Sub item 2" /> </menu> </item> </menu>
其中通過 <group android:checkableBehavior="single"> 設定一組菜單項為至多只有一個可被選中,非常適合用于通過導航抽屜切換呈現的 Fragment,若需要默認選中一個菜單項則只需要給指定 item 加上 android:checked="true" 即可。并且可以通過子菜單的形式顯示分割線和子標題。
到此為止布局文件部分就完成了,接下來只需要在Activity中設置監聽器即可:
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout); NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view); if (navigationView != null) { navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() { @Override public boolean onNavigationItemSelected(MenuItem menuItem) { //切換相應 Fragment 等操作 menuItem.setChecked(true); mDrawerLayout.closeDrawers(); return false; } }); }
至此導航抽屜就基本完成了,但 Material Design 中建議導航抽屜應該在 status bar 上也顯示,而 Android 5.0 及以上版本支持這一特性,因此還需要進一步處理。
針對 Android 5.0 及以上版本
首先由 window 來繪制 status bar 的背景,否則 status bar 為系統默認背景(原生是黑色背景),而 AppCompat 的主題已帶如下屬性:
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
確保 Android 5.0 以上版本使用的主題中并沒有把該屬性設置成 false 即可。
而通過 window 來繪制 status bar 的背景并不一定是我們需要的最終結果,因為 status bar 的背景在需要呈現的內容上和導航抽屜上不一定是一樣的,而通過 window 來繪制則肯定是一樣的,因此把 window 繪制的 status bar 的背景設置為透明,在 Android 5.0 以上版本使用的主題中加入如下代碼:
<item name="android:statusBarColor">@android:color/transparent</item>
接下來只需要 DrawerLayout 來接管 status bar 的背景的繪制工作即可,給布局文件中的 DrawerLayout 加入如下屬性:
android:fitsSystemWindows="true"
此時導航抽屜已經能夠顯示在 status bar 上。
至此理論上 Android 2.1 以上版本都能正常顯示導航抽屜了,完整代碼可參照 Github 上的一個 Demo 。
通過 Navigation View 能夠實現上圖所示的導航抽屜,但有兩處若不設置依舊會占著控件,十分不合理,分別是圖標以及 4 處的子菜單標題。所以若需要沒有圖標的項目或單獨加分割線則還得考慮使用自定義布局的形式實現導航抽屜。
但 Navigation View 優點依舊很明顯,首先設置的圖標經測試會被改變成合適的顏色,無論是選中還是未選中狀態,無需任何代碼即可達成下圖效果,若使用自定義布局的形式可能需要設計未選中和選中兩套圖標或自己寫代碼動態改變顏色。
若還是覺得 Navigation View 不夠好,又覺得自定義太麻煩,并且只需要兼容到 Android 2.3.3 或以上版本的話可以考慮使用使用 MaterialDrawer 開源控件,十分強大,能夠實現 Navigation View 所有能夠實現的效果,并且自由度更高,我通過這個開源控件完成了我畢業設計中所需的兩個導航抽屜,具體效果如下圖所示:
參考資料
Android Design Support Library (Android Developers Blog)