NavigationView表示應用程序的標準導航菜單,菜單內容可以由菜單資源文件填充。NavigationView通常放在DrawerLayout中,可以實現側滑效果的UI。DrawerLayout佈局可以有3個子佈局,第一個佈局必須是主界面且不可以不寫,其他2個子佈局就是左、右兩個側滑佈局,左右兩個側滑佈局可以只寫其中一個。下面就開始NavigationView的實練。
使用NavigationView控件需要導入design依賴包(我的運行環境是Android Studio 3.0,此版本中導入依賴包的關鍵字 不再是“compile”,而是改爲了“implementation”,這裏說明一下)
implementation 'com.android.support:recyclerview-v7:28.0.0-rc02'
先介紹下NavigationView控件的幾個屬性:
android:layout_gravity 值爲start則是從左側滑出,值爲end則是從右側滑出 app:menu NavigationView是通過菜單形式在佈局中放置元素的,值爲自己創建的菜單文件 app:headerLayout 給NavigationView設置頭文件 app:itemTextColor 設置菜單文字的顏色 app:itemIconTint 設置菜單圖標的顏色 app:itemBackground 設置菜單背景的顏色
下面一步步看下以上屬性的效果。佈局文件如下:
<?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:layout_width="match_parent" android:layout_height="match_parent" tools:context=".SNavigationViewActivity"> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="這是導航視圖NavigationView"/> </LinearLayout> <android.support.design.widget.NavigationView android:id="@+id/navigation_view_left" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="start"> </android.support.design.widget.NavigationView> <android.support.design.widget.NavigationView android:id="@+id/navigation_view_right" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="end"> </android.support.design.widget.NavigationView> </android.support.v4.widget.DrawerLayout>
運行效果如圖:
因爲剛剛沒有給NavigationView創建菜單元素,所有左側滑動和右側滑動都是空白,現在增加菜單元素。在menu文件夾下新建菜單文件snavigation_view.xml文件:
<?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android"> <group> <item android:id="@+id/item_argu" android:title="論壇" android:icon="@drawable/ic_menu_argu"/> </group> <group> <item android:id="@+id/item_book" android:title="頭條" android:icon="@drawable/ic_menu_book"/> </group> <group> <item android:id="@+id/item_cloud" android:title="雲空間" android:icon="@drawable/ic_menu_cloud"/> </group> <group> <item android:id="@+id/item_load" android:title="下載" android:icon="@drawable/ic_menu_load"/> </group> <group> <item android:id="@+id/item_rili" android:title="日曆" android:icon="@drawable/ic_menu_rili"/> </group> <group> <item android:id="@+id/item_star" android:title="收藏" android:icon="@drawable/ic_menu_star"/> </group> </menu>
在左右兩個NavigationView控件中增加菜單元素:
<android.support.design.widget.NavigationView android:id="@+id/navigation_view_left" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="start" app:menu="@menu/snavigation_view"> </android.support.design.widget.NavigationView> <android.support.design.widget.NavigationView android:id="@+id/navigation_view_right" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="end" app:menu="@menu/snavigation_view"> </android.support.design.widget.NavigationView>
運行效果如下:
下面給NavigationView增加頭部佈局,snavigation_view_header.xml如下:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="200dp" android:orientation="vertical" android:gravity="center" android:background="@drawable/snavi_header_bg"> <ImageView android:layout_width="50dp" android:layout_height="50dp" android:src="@drawable/avator"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="摸爬滾打的程序媛" android:padding="5dp" android:textColor="#FFFFFF"/> </LinearLayout>
<android.support.design.widget.NavigationView android:id="@+id/navigation_view_left" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="start" app:menu="@menu/snavigation_view" app:headerLayout="@layout/snavigation_view_header"> </android.support.design.widget.NavigationView> <android.support.design.widget.NavigationView android:id="@+id/navigation_view_right" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="end" app:menu="@menu/snavigation_view" app:headerLayout="@layout/snavigation_view_header"> </android.support.design.widget.NavigationView>
加完頭部佈局後運行再看一下效果:
爲了節省篇幅,下面就只以左側滑動爲例進行其他屬性的講解。
設置菜單圖標、文字的顏色:
<android.support.design.widget.NavigationView android:id="@+id/navigation_view_left" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="start" app:menu="@menu/snavigation_view" app:headerLayout="@layout/snavigation_view_header" app:itemTextColor="#33a767" app:itemIconTint="#5fe935"> </android.support.design.widget.NavigationView>
運行效果如圖:
如果設置菜單項被選中時的顏色變化,可以爲圖標、文字創建一個顏色選擇器,未選中時是綠色,選中是紅色。在color文件夾下新建選擇器navigation_select.xml:
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:color="#ff2200" android:state_checked="true"/> <item android:color="#33a767"/> </selector>
此時要注意的是,菜單文件snavigation_view.xml中的group標籤要增加android:checkableBehavior="single"屬性,否則看不到變化。
<android.support.design.widget.NavigationView android:id="@+id/navigation_view_left" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="start" app:menu="@menu/snavigation_view" app:headerLayout="@layout/snavigation_view_header" app:itemTextColor="@color/navigation_select" app:itemIconTint="@color/navigation_select"> </android.support.design.widget.NavigationView>
運行效果如圖:
以上實現的效果中是沒有Toolbar的,下面實現一下DrawerLayout和Toolbar進行關聯後的效果。
修改佈局文件如下:
<?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=".NavigationViewActivity"> <android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?actionBarSize" android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" android:background="@color/colorPrimary"> </android.support.v7.widget.Toolbar> <android.support.v4.widget.DrawerLayout android:id="@+id/drawerlayout" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1"> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="這是導航視圖NavigationView"/> </LinearLayout> <android.support.design.widget.NavigationView android:id="@+id/navigation_view_left" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="start" app:menu="@menu/snavigation_view" app:headerLayout="@layout/snavigation_view_header" app:itemTextColor="@color/navigation_select" app:itemIconTint="@color/navigation_select"> </android.support.design.widget.NavigationView> </android.support.v4.widget.DrawerLayout> </LinearLayout>
代碼:
public class NavigationViewActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener { private Toolbar toolbar; //要導入v7包下的 private DrawerLayout drawerLayout; private NavigationView navigationView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_navigation_view); toolbar=findViewById(R.id.toolbar); drawerLayout=findViewById(R.id.drawerlayout); navigationView=findViewById(R.id.navigation_view_left); //讓DrawerLayout和Toolbar進行聯動 順序很重要! setSupportActionBar(toolbar); //讓toolbar去取代actionbar getSupportActionBar().setDisplayHomeAsUpEnabled(true); //顯示toolbar //下面的代碼主要通過actionbardrawertoggle將toolbar與drawablelayout關聯起來 ActionBarDrawerToggle actionBarDrawerToggle=new ActionBarDrawerToggle(this,drawerLayout,toolbar,0,0); drawerLayout.addDrawerListener(actionBarDrawerToggle); //設置監聽 actionBarDrawerToggle.syncState(); //同步 //設置navigationView中菜單的點擊事件 navigationView.setNavigationItemSelectedListener(this); } @Override public boolean onNavigationItemSelected(@NonNull MenuItem item) { drawerLayout.closeDrawers(); //點擊菜單則收回drawerLayout return true; } }
運行效果如下:
讓DrawerLayout和Toolbar進行聯動之後,Toolbar左上角的圖標是隨着DrawerLayout滑出、收起而變化的。
關於NavigationView的補充:
1、實現菜單分割線,可以通過group實現,上面的菜單文件中,給每個group添加id屬性後,運行就可以看到菜單之間的分割線了,效果如圖:
2、想要動態修改菜單列表,可以通過以下代碼實現。
MenuItem menuItem = navigationView.getMenu().findItem(R.id.menu_item);
menuItem.setVisible(false); // true 爲顯示,false 爲隱藏
3、每個菜單項只有圖標、文字,不能添加其他控件。無法設置每個菜單項的間隔距離。如果想要實現豐富佈局的導航菜單,可以嘗試將NavigationView控件替換成其他控件,如ListView,頭佈局可以通過listview的addHeaderView(),每個item可以根據需求定義自己的菜單佈局。