NavigationView 的引入讓 Android 側邊欄實現(xiàn)起來相當方便,最近公司項目中也使用這個新的控件完成了側邊欄的改版。在使用過程中遇到一些坑,寫篇博文記錄一下。 本文分為兩大主要部分,第一部分是基本使用,第二部分是各種使用小細節(jié)(坑),如果你對其使用已經(jīng)熟悉了,可以跳過第一部分。 基本使用1. NavigationView 在 design 庫中,添加依賴(最新的是 23.2.0);compile 'com.android.support:design:23.1.1'
2. 然后在 DrawerLayout 布局中添加 NavigationView ;<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout
android:id="@+id/drawer_layout"
xmlns:android="http://schemas./apk/res/android"
xmlns:app="http://schemas./apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="@+id/main"
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="@color/colorPrimary"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"/>
......
</LinearLayout>
</FrameLayout>
<android.support.design.widget.NavigationView
android:id="@+id/navigation"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
app:headerLayout="@layout/nav_header"
app:menu="@menu/activity_main_drawer"/>
</android.support.v4.widget.DrawerLayout>
其中需要注意給 NavigationView 設置 android:layout_gravity="start" 屬性。 3.然后注意到 NavigationView 其實是分兩個部分的,一個是頭部,一個是下面的菜單列表部分,如下圖所示:其中頭部通過 app:headerLayout="@layout/nav_header" 屬性添加,nav_header 的布局如下: <?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas./apk/res/android"
android:layout_width="match_parent"
android:layout_height="192dp"
android:theme="@style/ThemeOverlay.AppCompat.Dark">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/nav_header_bg"
android:scaleType="centerCrop"/>
<ImageView
android:layout_width="96dp"
android:layout_height="96dp"
android:layout_gravity="bottom"
android:layout_marginBottom="36dp"
android:padding="8dp"
android:src="@drawable/ic_avatar"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:padding="16dp"
android:text="Jaeger"
android:textAppearance="@style/TextAppearance.AppCompat.Body1"/>
</FrameLayout>
下面的菜單列表部分是一個 menu 文件,通過 app:menu="@menu/activity_main_drawer" 屬性添加。 activity_main_drawer.xml 文件在 menu 文件夾下,內(nèi)容為:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas./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>
4. 菜單列表的點擊事件菜單列表的點擊事件設置代碼如下: navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(MenuItem item) {
switch (item.getItemId()){
case R.id.nav_personal_info:
// do something
break;
...
}
return false;
}
});
至此,NavigationView 的基本使用就差不多搞定了,效果就是前面圖片顯示的效果。接下來是各種填坑環(huán)節(jié)。?? 使用小細節(jié)(和坑)在舊版本中,假如你要獲得 NavigationView 中的頭像 ImageView ,你可以在 activity 中直接調(diào)用 findViewById() 方法來獲得。但是在 Support Library 23.1.0 版本之后,這個不再適用,在我使用的 Support Library 23.1.1 版本中,可以直接調(diào)用 getHeaderView() 方法先得到 Header,然后在通過header來獲得頭部內(nèi)的控件。 View headerView = navigationView.getHeaderView(0);
ImageView ivAvatar = (ImageView) headerView.findViewById(R.id.nav_avatar);
然后就可以進行各種愉快的頭像設置,用戶名設置了~ 關于這個問題,如果你用的不是23.1.1版本的話,你可以看 stackoverflow 上的討論 NavigationView get/find header layout,針對其他版本也有解決方法說明。 2. 菜單列表中的圖標不顯示原始顏色當設計師為每一項的圖標都設置了不同的顏色時,你將切好的彩色圖標文件放進去,運行后發(fā)現(xiàn)全變成灰色了。此時可以通過 app:itemIconTint="@color/blue" 為圖標統(tǒng)一設置顏色,前后效果如下: 然而這還不是我們需要的效果,我們需要的是彩色的圖標,而不是統(tǒng)一的圖標顏色。 解決方法是調(diào)用 NavigationView 的 setItemIconTintList(ColorStateList tint) 方法,傳入 null 參數(shù): navigationView.setItemIconTintList(null);
最終效果如下: 3. 添加分割線如上面的截圖所示,菜單列表分成了兩個部分,中間用一個分割線隔開。解決方法是在 menu 文件中分成多個 group ,且為每個 group 設置 id ,如下: <?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas./apk/res/android">
<group
android:id="@+id/first_group"
android:checkableBehavior="none">
<item
android:id="@+id/nav_personal_info"
android:icon="@drawable/nav_personal_info"
android:title="@string/personal_info_setting"/>
...
<item
android:id="@+id/nav_system_setting"
android:icon="@drawable/nav_setting"
android:title="@string/system_setting"/>
</group>
<group android:id="@+id/second_group">
<item
android:id="@+id/nav_score"
android:icon="@drawable/nav_score"
android:title="@string/score"/>
<item
android:id="@+id/nav_feedback"
android:icon="@drawable/nav_feedback"
android:title="@string/feedback"/>
</group>
</menu>
4. 隱藏某個菜單列表項公司項目會根據(jù)你是否是管理員,來控制某個菜單列表項的顯示和隱藏,因此就出現(xiàn)了這個問題。 原以為比較麻煩,后來搜了下,也比較簡單地解決了,直接上代碼: MenuItem menuItem = navigationView.getMenu().findItem(R.id.some_menu_item);
menuItem.setVisible(false); // true 為顯示,false 為隱藏
這個問題也就這么解決了。?? 5. 使用 NavigationView 時透明狀態(tài)欄的處理這個問題可以看我上一篇文章來解決 Android App 沉浸式狀態(tài)欄解決方案,里面會講到如何處理抽屜視圖的透明狀態(tài)欄的實現(xiàn)。 寫在最后- 目前來說 NavigationView 的定制性還是很不友好的,后面有時間研究下為其自定義布局,或者繼承重寫一個好用的 NavigationView。
- 在使用 NavigationView 過程中,也有很多自己一開始不知道怎么解決的問題,通過 Google 搜索基本都找到了答案,同時現(xiàn)在也開始使用英文搜索,發(fā)現(xiàn)確實好用很多,果然如之前一個笑話所說——普通程序猿 + 搜索引擎 = 中高級程序猿。哈哈哈~ 雖說是笑話,不過使用好搜索引擎確實能解決很多問題。
如發(fā)現(xiàn)本文中錯誤或者提出建議,請評論或聯(lián)系我,謝謝。
|