最詳細的 Android NavigationDrawer 開發實踐總結
繼前面寫的兩篇文章之後( 有問題歡迎反饋哦 ):
接著來寫寫Android系統UI新特性,本文是我對最近開發過程中應用 NavigationDrawer 特性的詳細總結。 本文涉及到的所有程式碼實現細節,會在文末附上原始碼地址。有問題歡迎在下方留言討論 。
NavigationDrawer 簡介
NavigationDrawer是 Google 在 Material Design 中推出的一種側滑導航欄設計風格。說起來可能很抽象,我們直接來看看 網易雲音樂 的側滑導航欄效果
網易雲音樂側滑導航欄效果
Google 為了支援這樣的導航效果,推出一個新控制元件 —— DrawerLayout 。而在 DrawerLayout 沒誕生之前,需求中需要實現側滑導航效果時,我們必然會選擇去選擇一些成熟的第三方開源庫(如最有名的 SlidingMenu )來完成開發 。效果上,普遍都像 手Q 那樣:
手Q的SlidingMenu實現側滑效果
在對比過 DrawerLayout 和 SlidingMenu 的實現效果後,基於以下的幾點,我認為完全可以在開發中使用 DrawerLayout 取代以前的 SlidingMenu :
- 從動畫效果上看,你會發現兩者僅僅是在移動的效果上有些差別外,其他地方並沒有太大的差異
- 在互動效果上,我認為這兩者都差不多的,就算你把 網易雲音樂 的效果套到了 手Q 上,也不會影響到使用者的互動
- DrawerLayout 用起來比 SlidingMenu 更簡單,程式碼量更少(往下看就知道了)
- DrawerLayout 是向下相容的,所以不會存在低版本相容性問題
- Google 親兒子,沒理由不支援啊!!!!!!
到這裡,要是你還沒有引入 DrawerLayout 開發的衝動,請繼續聽我為你好好安利一番。
初識 DrawerLayout
一般情況下,在 DrawerLayout 佈局下只會存在兩個子佈局,一個 內容佈局 和 一個 側滑選單佈局 ,這兩個佈局關鍵在於 android:layout_gravity 屬性的設定。如果你想把其中一個子佈局設定成為左側滑選單,只需要設定 android:layout_gravity=”start” 即可(也可以是 left,右側滑則為 end 或 right ),而沒有設定的佈局則自然成為 內容佈局 。那麼,使用 DrawerLayout 到底有多簡單呢,我們先直接看看下面的佈局檔案
layout/activity_simple_drawer.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.support.v4.widget.DrawerLayout android:id="@+id/simple_navigation_drawer" android:layout_width="match_parent" android:layout_height="match_parent"> <!--內容檢視--> <include android:id="@+id/tv_content" layout="@layout/drawer_content_layout" android:layout_width="match_parent" android:layout_height="match_parent" /> <!--左側滑選單欄--> <include layout="@layout/drawer_menu_layout" android:layout_width="250dp" android:layout_height="match_parent" android:layout_gravity="start" /> <!--右側滑選單欄--> <include layout="@layout/drawer_menu_layout" android:layout_width="250dp" android:layout_height="match_parent" android:layout_gravity="end" /> </android.support.v4.widget.DrawerLayout> </RelativeLayout>
到此,你在 Activity 裡面什麼都不用做,就已經完成了下面側滑效果的實現了,簡單到害怕有木有。
最簡單的側滑效果實現
在欣賞著 DrawerLayout 簡單方便的同時,Google 也為我們提供了 DrawerLayout 很多常用的API,其中包括:開啟或關閉側滑欄、控制側滑欄的方向、設定滑動時漸變的陰影顏色和監聽滑動事件等。
SimpleDrawerActivity執行效果
具體詳細程式碼請參加工程中的 SimpleDrawerActivity,此處就不貼程式碼了。還有一處 DrawerLayout 使用的小細節需要溫馨提醒一下,有一次,我手誤把 DrawerLayout 的 android:layout_width 設定成 wrap_content ,就出現下面的異常了
DrawerLayout的wrap_content錯誤
遇到過相同情況的童鞋,只需要把 android:layout_width 設定成 match_parent 即可。
再識 NavigationView
在 Google 推出 NavigationDrawer 設計中, NavigationView 和 DrawerLayout 是官方推薦的最佳組合。在使用 NavigationView 前,因為它是在 Material Design 的相容包中,所以需要先在 build.gradle 中引入
compile 'com.android.support:design:23.1.1'
這裡因為我工程配置的 compileSdkVersion 是 23 ,所以需要引入 com.android.support:design:23.x.x 的版本。需要吐槽的是,這裡如果你引入了 com.android.support:design:23.1.0 ,工程執行後 NavigationView 會報一個 android.view.InflateException:xxxxxx 的錯誤(又是一個大坑)。
接下來簡單的介紹一下 NavigationView 的使用,我們繼續看看幾個相關佈局檔案 layout/activity_simple_navigation_drawer.xml 、 layout/navigation_drawer_header.xml 、 menu/navigation_drawer_menu.xml 和 實現效果:
layout/activity_simple_navigation_drawer.xml
<?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" android:id="@+id/drawer" android:layout_width="match_parent" android:layout_height="match_parent"> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <TextView android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:text="NavigationDrawerContent" /> </LinearLayout> <android.support.design.widget.NavigationView android:id="@+id/navigation_view" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_gravity="start" app:headerLayout="@layout/navigation_drawer_header" app:menu="@menu/navigation_drawer_menu" /> </android.support.v4.widget.DrawerLayout>
layout/navigation_drawer_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="250dp" android:background="@color/color_512da8"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_alignParentLeft="true" android:layout_margin="10dp" android:text="HeaderLayout" android:textColor="@android:color/white" android:textSize="18sp" /> </RelativeLayout>
menu/navigation_drawer_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/item_green" android:icon="@mipmap/green" android:title="Green" /> <item android:id="@+id/item_blue" android:icon="@mipmap/blue" android:title="Blue" /> <item android:id="@+id/item_pink" android:icon="@mipmap/pink" android:title="Pink" /> </group> <item android:title="SubItems"> <menu> <item android:id="@+id/subitem_01" android:icon="@mipmap/ic_launcher" android:title="SubItem01" /> <item android:id="@+id/subitem_02" android:icon="@mipmap/ic_launcher" android:title="SubItem02" /> <item android:id="@+id/subitem_03" android:icon="@mipmap/ic_launcher" android:title="SubItem03" /> </menu> </item> <item android:title="SubItems"> <menu> <item android:id="@+id/subitem_04" android:icon="@mipmap/ic_launcher" android:title="SubItem04" /> <item android:id="@+id/subitem_05" android:icon="@mipmap/ic_launcher" android:title="SubItem05" /> <item android:id="@+id/subitem_06" android:icon="@mipmap/ic_launcher" android:title="SubItem06" /> </menu> </item> </menu>
最終得到下面的效果
activity_simple_navigation_drawer.xml實現效果
總的來說, NavigationView 比較關鍵的屬性就只有 app:headerLayout 和 app:menu ,它們分別對應效果圖中頂部的 紫色區域(layout/navigation_drawer_header.xml) 和 下方的 填充選單項(menu/navigation_drawer_menu.xml) 。其實是用起來也和 DrawerLayout 一樣,非常簡單。
不實用的 NavigationView
其實談到 NavigationView,個人認為它設計並不實用,而且是比較呆板的。最直接的一點是,它的選單圖示
NavigationView預設圖示顏色
第一次執行程式碼的時候,把我五顏六色的圖示居然跑出來這效果,差點沒一口水噴在螢幕上。好在程式碼中可以呼叫下面這個API
mNavigationView.setItemIconTintList(null);//設定選單圖示恢復本來的顏色
還原選單圖示廬山真面目。(著實看不懂 Google 的設計了…)
其次,是關於選單相中圖示大小和文字間距之類的設定,從 Google 的設計文件來看,
NavigationView設計
NavigationView 基本已經規定設定好了大小距離,留給我們可以改動的空間並不多。如果你想調整一下選單的佈局寬高之類的,基本是不可能的了(即使可能,也估計非常蛋疼)。所以,目前我基本還沒見過國內哪個 app 是直接使用了 NavigationView 來做導航(如果有的話,歡迎告知一下)。
以上關於 NavigationView 不實用,僅是本人的一些看法,如果你有不同看法,歡迎留言討論。為了加深一下 NavigationDrawer 設計的實踐,下面來大致的模仿實現網易雲音樂的導航效果。
仿網易雲音樂的 NavigationDrawer 實現
先來看看網易雲音樂的效果
雲音樂導航選單
主要就是一個線性佈局的選單並結合了 Translucent System Bar 的特性(還不知道的童鞋請看我前面寫的文章哈),下面就直接看看大致實現的佈局檔案 :
layout/activity_cloud_music.xml
<?xml version="1.0" encoding="utf-8"?> <android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/drawer" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/color_cd3e3a"> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:fitsSystemWindows="true" android:orientation="vertical"> <TextView android:layout_width="match_parent" android:layout_height="65dp" android:background="@color/color_cd3e3a" android:gravity="center" android:text="網易雲音樂" android:textColor="@android:color/white" android:textSize="18sp" /> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:background="@android:color/white" android:orientation="vertical"> </LinearLayout> </LinearLayout> <LinearLayout android:id="@+id/navigation_view" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="start" android:background="@android:color/white" android:fitsSystemWindows="true" android:orientation="vertical"> <ImageView android:layout_width="match_parent" android:layout_height="180dp" android:scaleType="centerCrop" android:src="@mipmap/topinfo_ban_bg" /> <LinearLayout android:layout_width="match_parent" android:layout_height="50dp" android:gravity="center_vertical" android:orientation="horizontal"> <ImageView android:layout_width="40dp" android:layout_height="40dp" android:layout_marginLeft="10dp" android:layout_marginRight="10dp" android:src="@mipmap/topmenu_icn_msg" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="我的訊息" android:textColor="@android:color/black" android:textSize="15sp" /> </LinearLayout> ... ... ... </LinearLayout> </android.support.v4.widget.DrawerLayout>
最終即可實現類似網易雲音樂的效果。
仿造網易雲音樂
彩蛋
彩蛋一:左上角的導航動畫效果實現
左上角的導航動畫
經常會看有些 app 的左上角有這些帶感的導航動畫,之前想要引入這種效果,都是來自第三方的開原始碼,諸如下面兩個比較有名的:
而現在再也不需要了,Google 推出的 ActionBarDrawerToggle 也能實現這樣的效果了,具體檢視我在 NavigationDrawerAnimationActivity 中的實現程式碼
ActionBarDrawerToggle實現效果
如果你對上面這種動畫,效果不滿意,也可以考慮一下 material-menu 的另一種實現效果。
material-menu動畫效果
彩蛋二:比 NavigationView 更好的選擇
前面提到 NavigationView 的不實用性,如果你真的要實現 NavigationView那樣的效果,又渴望比較高的自由度。這個功能強大且自由度很高的開源庫 MaterialDrawer 應該是個很不錯的選擇。
MaterialDrawer 效果圖一
MaterialDrawer 效果圖二
總結
到此,對於 NavigationDrawer 的實踐總結基本結束。整體給我的感覺是,自從 Material Design 設計開始推出後,Google 推出的這些新控制元件使用起來更加簡單,這能讓我們更好的把精力放在編寫業務程式碼上。很多以前需要藉助第三方開源庫才能實現的效果,現在已經慢慢的不需要了。當然,我們依舊可以去深入的學習這些優秀開原始碼,沉澱到更多的乾貨。這樣,小菜也就慢慢成為大牛了。
分享即美德,原始碼請看: https://github.com/D-clock/AndroidSystemUiTraining ,本篇的主要實現程式碼如下紅圈所示
主要示例程式碼
相關文章
- 最詳細的 NavigationDrawer 開發實踐總結Navigation
- 最詳細的 Android Toolbar 開發實踐總結Android
- Android開發:最詳細的 Toolbar 開發實踐總結Android
- 小程式開發實踐總結
- Taro實踐 - 深度開發實踐體驗及總結
- 這或許是最詳細的JUC多執行緒併發總結執行緒
- Vue3 + TypeScript 開發實踐總結VueTypeScript
- TypeScript 在開發應用中的實踐總結TypeScript
- 我的 Android 開發實戰經驗總結Android
- Mac版最詳細的Flutter開發環境搭建MacFlutter開發環境
- Android Service和IntentService知識點詳細總結AndroidIntent
- Canal詳細入門實戰(使用總結)
- 最詳細的自定義Spring Boot Starter開發教程Spring Boot
- Material Design之 AppbarLayout 開發實踐總結Material DesignAPP
- vue+elementUI開發實踐問題總結(二)VueUI
- float浮動的詳細總結
- 我理解的測試開發與實踐總結——新人篇
- 全網最詳細的一篇Flutter 尺寸限制類容器總結Flutter
- 《Android和PHP開發最佳實踐》一3.7 小結AndroidPHP
- Threejs 開發 3D 地圖實踐總結JS3D地圖
- iOS 應用開發中的斷點續傳實踐總結iOS斷點
- 最棒 Spring Boot 乾貨總結(超詳細,建議收藏)Spring Boot
- Glide詳細使用總結IDE
- Android開發經驗總結Android
- Android TV開發總結【RecycleView】AndroidView
- Android 開發功能模組總結Android
- Flutter、Android混合開發實踐FlutterAndroid
- Android模組化開發實踐Android
- Android元件化開發實踐Android元件化
- 最實用VS code開發測試利器,超詳細python配置指南Python
- Android的核取方塊的詳細開發案例分析Android
- android夯實總結(設計、細節及思想)Android
- Vue開發總結 及 一些最佳實踐 (已更新)Vue
- 五步搞定Android開發環境部署——非常詳細的Android開發環境搭建教程Android開發環境
- Android 日常開發問題總結Android
- Android開發技術面總結Android
- android開發之svg全面總結AndroidSVG
- Android 開發知識點總結Android