本文和接下來的幾篇文章為閱讀郭霖先生所著《第一行代碼:Android(篇第2版)》的學習筆記,按照書中的內容順序進行記錄,書中的Demo本人全部都做過了。 每一章節本人都做了詳細的記錄,以下是我學習記錄(包含大量書中內容的整理和自己在學習中遇到的各種bug及解決方案),方便以後閱讀和查閱。最後,非常 ...
本文和接下來的幾篇文章為閱讀郭霖先生所著《第一行代碼:Android(篇第2版)》的學習筆記,按照書中的內容順序進行記錄,書中的Demo本人全部都做過了。
每一章節本人都做了詳細的記錄,以下是我學習記錄(包含大量書中內容的整理和自己在學習中遇到的各種bug及解決方案),方便以後閱讀和查閱。最後,非常感激郭霖先生提供這麼好的書籍。
第12章 最佳的UI體驗——Material Design實戰
其實長久以來,大多數人都認為Android系統的UI並不算美觀,至少沒有iOS系統的美觀。以至於很多IT公司在進行應用界面設計的時候,為了保證雙平臺的統一性,強制要求Android端的界面風格必須和iOS端一致。
這種情況在現實工作當中實在是太常見了,因為對於一般用戶來說,他們不太可能會在兩個操作系統上分別去使用同一個應用,但是卻必定會在同一個操作系統上使用不同的應用。因此,同一個操作系統中各個應用之間的界面統一性要遠比一個應用在雙平臺的界面統一性重要得多,只有這樣,才能給使用者帶來更好的用戶體驗。
但問題在於,Android標準的界面設計風格並不是特別被大眾所接受,很多公司都覺得自己完全可以設計出更加好看的界面,從而導致Android平臺的界面風格長期難以得到統一。為瞭解決這個問題,谷歌也是祭出了殺手鐧,在2014年Google I/O大會上重磅推出了一套全新的界面設計語言——MaterialDesign。
本章我們就將對Material Design進行一次深入的學習。
12.1 什麼是Material Design
Material Design是由谷歌的設計工程師們基於傳統優秀的設計原則,結合豐富的創意和科學技術所發明的一套全新的界面設計語言,包含了視覺、運動、互動效果等特性。那麼谷歌憑什麼認為Material Design就能解決Android平臺界面風格不統一的問題呢?一言以蔽之,好看!
這次谷歌在界面設計上確實是下足了功夫,很多媒體評論,MaterialDesign的出現使得Android首次在UI方面超越了iOS。按照正常的思維來想,如果各個公司都無法設計出比Material Design更出色的界面風格,那麼它們就應該理所當然地使用Material Design來設計界面,從而也就能解決Android平臺界面風格不統一的問題了。
為了做出表率,谷歌從Android 5.0系統開始,就將所有內置的應用都使用Material Design風格來進行設計。可以先欣賞一下,如圖:
其中,左邊的應用是Play Store,右邊的應用是YouTube。可以看出,它們的界面都十分美觀,而它們正是使用Material Design來進行設計的。
不過,在重磅推出之後,Material Design的普及程度卻不能說是特別理想。因為這隻是一個推薦的設計規範,主要是面向UI設計人員的,而不是面向開發者的。很多開發者可能根本就搞不清楚什麼樣的界面和效果才叫MaterialDesign,就算搞清楚了,實現起來也會很費勁,因為不少Material Design的效果是很難實現的,而Android中卻幾乎沒有提供相應的API支持,一切都要靠開發者自己從零寫起。
谷歌當然也意識到了這個問題,於是在2015年的Google I/O大會上推出了一個Design Support庫,這個庫將Material Design中最具代表性的一些控制項和效果進行了封裝,使得開發者在即使不瞭解Material Design的情況下也能非常輕鬆地將自己的應用Material化。
本章中我們就將對Design Support這個庫進行深入的學習,並且配合一些其他的控制項來完成一個優秀的MaterialDesign應用。新建一個MaterialTest項目,然後我們馬上開始吧!
12.2 Toolbar
回憶一下,我們曾經在3.4.1小節為了使用一個自定義的標題欄,而把系統原生的ActionBar隱藏掉。沒錯,每個活動最頂部的那個標題欄其實就是ActionBar,之前我們編寫的所有程式里一直都有ActionBar的身影。
不過,ActionBar由於其設計的原因,被限定只能位於活動的頂部,從而不能實現一些Material Design的效果,因此官方現在已經不再建議使用ActionBar了。那麼本書中我也就不准備再介紹ActionBar的用法了,而是直接講解現在更加推薦使用的Toolbar。
Toolbar的強大之處在於,它不僅繼承了ActionBar的所有功能,而且靈活性很高,可以配合其他控制項來完成一些Material Design的效果,下麵我們就來具體學習一下。
首先你要知道,任何一個新建的項目,預設都是會顯示ActionBar的。那麼這個ActionBar到底是從哪裡來的呢?其實這是根據項目中指定的主題來顯示的,打開AndroidManifest.xml文件看一下,如下所示:
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.MaterialTest">
...
</application>
可以看到,這裡使用android:theme
屬性指定了一個AppTheme的主題。那麼這個AppTheme又是在哪裡定義的呢?打開res/values/themes.xml文件,代碼如下所示:
<resources xmlns:tools="http://schemas.android.com/tools">
<!-- Base application theme. -->
<style name="Theme.MaterialTest" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
<!-- Primary brand color. -->
<item name="colorPrimary">@color/purple_500</item>
<item name="colorPrimaryVariant">@color/purple_700</item>
<item name="colorOnPrimary">@color/white</item>
<!-- Secondary brand color. -->
<item name="colorSecondary">@color/teal_200</item>
<item name="colorSecondaryVariant">@color/teal_700</item>
<item name="colorOnSecondary">@color/black</item>
<!-- Status bar color. -->
<item name="android:statusBarColor" tools:targetApi="l">?attr/colorPrimaryVariant</item>
<!-- Customize your theme here. -->
</style>
</resources>
這裡定義了一個叫AppTheme的主題,然後指定它的parent主題是Theme.AppCompat.Light. DarkActionBar。這個DarkActionBar是一個深色的ActionBar主題,我們之前所有的項目中自帶的ActionBar就是因為指定了這個主題才出現的。
現在準備使用Toolbar來替代ActionBar,因此需要指定一個不帶ActionBar的主題,通常有兩種主題可選:
Theme.AppCompat.NoActionBar表示深色主題,它會將界面的主體顏色設成深色,陪襯顏色設成淡色。
Theme.AppCompat.Light.NoActionBar表示淡色主題,它會將界面的主體顏色設成淡色,陪襯顏色設成深色。
具體的效果你可以自己動手試一試,這裡由於我們之前的程式一直都是以淡色為主的,那麼我就選用淡色主題了,如下所示:
<style name="Theme.MaterialTest" parent="Theme.AppCompat.Light.NoActionBar">
<item name="colorPrimaryDark">@color/design_default_color_primary_dark</item>
除了上述3個屬性之外,我們還可以通過,android:textColorPrimary,android:windowBackground,和android:navigationBarColor等屬性來控制更多位置的顏色。
colorAccent這個屬性比較難理解,它不只是用來指定這樣一個按鈕的顏色,而是更多表達了一個強調的意思,比如一些控制項的選中狀態也會使用colorAccent的顏色。
現在,我們已經將ActionBar隱藏起來了,那麼接下來看一看如何使用Toolbar來替代ActionBar。修改activity_main.xml中的代碼,如下所示:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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">
<androidx.appcompat.widget.Toolbar
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:id="@+id/toolbar"
android:background="?colorPrimary"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
android:popupTheme="@style/ThemeOverlay.AppCompat.Light"/>
</FrameLayout>
使用xmlns:app指定了一個新的命名空間。正是由於每個佈局文件都會使用xmlns:android來指定一個命名空間,因此我們才能一直使用android:id、android:layout_width等寫法,那麼這裡指定了xmlns:app,也就是說現在可以使用app:attribute這樣的寫法了。
但是為什麼這裡要指定一個xmlns:app的命名空間呢?這是由於Material Design是在Android 5.0系統中才出現的,而很多的Material屬性在5.0之前的系統中並不存在,那麼為了能夠相容之前的老系統,我們就不能使用android:attribute這樣的寫法了,而是應該使用app:attribute。
接下來定義了一個Toolbar控制項,給Toolbar指定了一個id,將它的寬度設置為match_parent,高度設置為actionBar的高度,背景色設置為colorPrimary。
不過下麵的部分就稍微有點難理解了,由於我們剛纔在themes.xml中將程式的主題指定成了淡色主題,因此Toolbar現在也是淡色主題,而Toolbar上面的各種元素就會自動使用深色系,這是為了和主體顏色區別開。但是這個效果看起來就會很差,之前使用ActionBar時文字都是白色的,現在變成黑色的會很難看。
那麼為了能讓Toolbar單獨使用深色主題,這裡我們使用android:theme屬性,將Toolbar的主題指定成了ThemeOverlay.AppCompat.Dark.ActionBar。但是這樣指定完了之後又會出現新的問題,如果Toolbar中有菜單按鈕(我們在2.2.5小節中學過),那麼彈出的菜單項也會變成深色主題,這樣就再次變得十分難看,於是這裡使用了app:popupTheme屬性單獨將彈出的菜單項指定成了淡色主題。之所以使用app:popupTheme,是因為popupTheme這個屬性是在Android 5.0系統中新增的,我們使用app:popupTheme的話就可以相容Android 5.0以下的系統了。
如果你覺得上面的描述很繞的話,可以自己動手做一做試驗,看看不指定上述主題會是什麼樣的效果,這樣你會理解得更加深刻。寫完了佈局,接下來我們修改MainActivity,代碼如下所示:
package com.zhouzhou.materialtest;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import android.os.Bundle;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
}
}
這樣我們就做到既使用了Toolbar,又讓它的外觀與功能都和ActionBar一致了。
這個標題欄我們再熟悉不過了,雖然看上去和之前的標題欄沒什麼兩樣,但其實它已經是Toolbar而不是ActionBar了。因此它現在也具備了實現MaterialDesign效果的能力,這個我們在後面就會學到。
接下來我們再學習一些Toolbar比較常用的功能吧,比如修改標題欄上顯示的文字內容。這段文字內容是在AndroidManifest.xml中指定的,如下所示:
...
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.MaterialTest">
<activity
android:name=".MainActivity"
android:label="Fruits"
...
</application>
...
給activity增加了一個android:label屬性,用於指定在Toolbar中顯示的文字內容,如果沒有指定的話,會預設使用application中指定的label內容,也就是我們的應用名稱。
只有一個標題的Toolbar看起來太單調了,還可以再添加一些action按鈕來讓Toolbar更加豐富一些,這裡我提前準備了幾張圖片來作為按鈕的圖標,將它們放在了drawable-xxhdpi目錄下。現在右擊res目錄→New→Directory,創建一個menu文件夾。然後右擊menu文件夾→New→Menu resource file,創建一個toolbar.xml文件,並編寫如下代碼:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/backup"
android:icon="@drawable/ic_backup"
android:title="Backup"
app:showAsAction="always"/>
<item
android:id="@+id/delete"
android:icon="@drawable/ic_delete"
android:title="Delete"
app:showAsAction="ifRoom"/>
<item
android:id="@+id/settings"
android:icon="@drawable/ic_settings"
android:title="Settings"
app:showAsAction="never"/>
</menu>
可以看到,我們通過<item>
標簽來定義action按鈕,android:id用於指定按鈕的id, android:icon用於指定按鈕的圖標,android:title用於指定按鈕的文字。
接著使用app:showAsAction來指定按鈕的顯示位置,之所以這裡再次使用了app命名空間,同樣是為了能夠相容低版本的系統。showAsAction主要有以下幾種值可選:
- always表示永遠顯示在Toolbar中,如果屏幕空間不夠則不顯示;
- ifRoom表示屏幕空間足夠的情況下顯示在Toolbar中,不夠的話就顯示在菜單當中;
- never則表示永遠顯示在菜單當中。
註意,Toolbar中的action按鈕只會顯示圖標,菜單中的action按鈕只會顯示文字。接下來的做法就和2.2.5小節中的完全一致了,修改MainActivity中的代碼,如下所示:
package com.zhouzhou.materialtest;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
}
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.toolbar,menu);
return true;
}
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.backup:
Toast.makeText(this, "You clicked Backup", Toast.LENGTH_SHORT).show();
break;
case R.id.delete:
Toast.makeText(this, "You clicked Delete", Toast.LENGTH_SHORT).show();
break;
case R.id.settings:
Toast.makeText(this, "You clicked Settings", Toast.LENGTH_SHORT).show();
break;
default:
}
return true;
}
}
在onCreateOptionsMenu()方法中載入了toolbar.xml這個菜單文件,然後在onOptionsItemSelected()方法中處理各個按鈕的點擊事件。現在重新運行一下程式,效果如圖:
可以看到,Toolbar上面現在顯示了兩個action按鈕,這是因為Backup按鈕指定的顯示位置是always, Delete按鈕指定的顯示位置是ifRoom,而現在屏幕空間很充足,因此兩個按鈕都會顯示在Toolbar中。
另外一個Settings按鈕由於指定的顯示位置是never,所以不會顯示在Toolbar中,點擊一下最右邊的菜單按鈕來展開菜單項,就能找到Settings按鈕了(菜單中的action按鈕只會顯示文字)。另外,這些action按鈕都是可以響應點擊事件的,你可以自己去試一試。Toolbar的功能還遠遠不只這些,後面會結合其他控制項來挖掘Toolbar的更多功能。
12.3 滑動菜單
滑動菜單可以說是Material Design中最常見的效果之一了,在許多著名的應用(如Gmail、Google+等)中,都有滑動菜單的功能。雖說這個功能看上去好像挺複雜的,不過藉助谷歌提供的各種工具,我們可以很輕鬆地實現非常炫酷的滑動菜單效果。
12.3.1 DrawerLayout
所謂的滑動菜單就是將一些菜單選項隱藏起來,而不是放置在主屏幕上,然後可以通過滑動的方式將菜單顯示出來。這種方式既節省了屏幕空間,又實現了非常好的動畫效果,是Material Design中推薦的做法。
不過,如果我們全靠自己去實現上述功能的話,難度恐怕就很大了。幸運的是,谷歌提供了一個DrawerLayout控制項,藉助這個控制項,實現滑動菜單簡單又方便。
DrawerLayout的用法,首先它是一個佈局,在佈局中允許放入兩個直接子控制項,第一個子控制項是主屏幕中顯示的內容,第二個子控制項是滑動菜單中顯示的內容。因此,我們就可以對activity_main.xml中的代碼做如下修改:
<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
android:popupTheme="@style/ThemeOverlay.AppCompat.Light"/>
</FrameLayout>
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="start"
android:text="This is menu"
android:textSize="30sp"
android:background="#FFF"/>
</androidx.drawerlayout.widget.DrawerLayout>
DrawerLayout中放置了兩個直接子控制項:
- 第一個子控制項是FrameLayout,用於作為主屏幕中顯示的內容,當然裡面還有我們剛剛定義的Toolbar。
- 第二個子控制項這裡使用了一個TextView,用於作為滑動菜單中顯示的內容,其實使用什麼都可以,DrawerLayout並沒有限制只能使用固定的控制項。
第二個子控制項有一點需要註意,android:gravity="start"
這個屬性是必須指定的,因為我們需要告訴DrawerLayout滑動菜單是在屏幕的左邊還是右邊:
-
指定left表示滑動菜單在左邊;
-
指定right表示滑動菜單在右邊;
-
指定start,表示會根據系統語言進行判斷;
如果系統語言是從左往右的,比如英語、漢語,滑動菜單就在左邊,如果系統語言是從右往左的,比如阿拉伯語,滑動菜單就在右邊。
只需要改動這麼多就可以了,現在重新運行一下程式,然後在屏幕的左側邊緣向右拖動,就可以讓滑動菜單顯示出來了,如圖:
然後向左滑動菜單,或者點擊一下菜單以外的區域,都可以讓滑動菜單關閉,從而回到主界面。無論是展示還是隱藏滑動菜單,都是有非常流暢的動畫過渡的。
可以看到,我們只是稍微改動了一下佈局文件,就能實現如此炫酷的效果。
過現在的滑動菜單還有點問題,因為只有在屏幕的左側邊緣進行拖動時才能將菜單拖出來,而很多用戶可能根本就不知道有這個功能,那麼該怎麼提示他們呢?
Material Design建議的做法是在Toolbar的最左邊加入一個導航按鈕,點擊了按鈕也會將滑動菜單的內容展示出來。這樣就相當於給用戶提供了兩種打開滑動菜單的方式,防止一些用戶不知道屏幕的左側邊緣是可以拖動的。
下麵,我們開始來實現這個功能。首先我準備了一張導航按鈕的圖標ic_menu.png,將它放在了drawable-xxhdpi目錄下。然後修改MainActivity中的代碼,如下所示:
public class MainActivity extends AppCompatActivity {
private DrawerLayout mDrawerLayout;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setHomeAsUpIndicator(R.drawable.ic_menu);
}
}
...
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.backup:
...
case android.R.id.home:
mDrawerLayout.openDrawer(GravityCompat.START);
break;
default:
}
return true;
}
}
首先調用findViewById()方法得到了DrawerLayout的實例,然後調用getSupportActionBar()方法得到了ActionBar的實例,雖然這個ActionBar的具體實現是由Toolbar來完成的。接著調用ActionBar的setDisplayHomeAsUpEnabled()方法讓導航按鈕顯示出來,又調用了setHomeAsUpIndicator()方法來設置一個導航按鈕圖標。
實際上,Toolbar最左側的這個按鈕就叫作HomeAsUp按鈕,它預設的圖標是一個返回的箭頭,含義是返回上一個活動。很明顯,這裡我們將它預設的樣式和作用都進行了修改。
接下來在onOptionsItemSelected()方法中對HomeAsUp按鈕的點擊事件進行處理,HomeAsUp按鈕的id永遠都是android.R.id.home。然後調用DrawerLayout的openDrawer()方法將滑動菜單展示出來,註意openDrawer()方法要求傳入一個Gravity參數,為了保證這裡的行為和XML中定義的一致,我們傳入了GravityCompat.START。
現在重新運行一下程式,效果如圖:
可以看到,在Toolbar的最左邊出現了一個導航按鈕,用戶看到這個按鈕就知道這肯定是可以點擊的。現在點擊一下這個按鈕,滑動菜單界面就會再次展示出來了。
12.3.2 NavigationView
目前我們已經成功實現了滑動菜單功能,其中滑動功能已經做得非常好了,但是菜單卻還很醜,畢竟菜單頁面僅僅使用了一個TextView,非常單調。有對比才會有落差,我們看一下Google+的滑動菜單頁面是長什麼樣的,如圖:
事實上,你可以在滑動菜單頁面定製任意的佈局,不過谷歌給我們提供了一種更好的方法——使用NavigationView。NavigationView是Design Support庫中提供的一個控制項,它不僅是嚴格按照Material Design的要求來進行設計的,而且還可以將滑動菜單頁面的實現變得非常簡單。接下來我們就學習一下NavigationView的用法。
首先,既然這個控制項是Design Support庫中提供的,那麼我們就需要將這個庫引入到項目中才行。打開app/build.gradle文件,在dependencies閉包中添加如下內容:
dependencies {
implementation 'com.android.support:design:28.0.0'
implementation 'de.hdodenhof:circleimageview:2.1.0'
}
註意:此時implementation 'com.android.support:design:28.0.0'
會有爆紅!
解決方式:推薦使用androidx下的庫。
第一種解決方式:
第二種解決方式:
將最新的com.android.support:design:28.0.0
改為com.google.android.material:material:1.0.0
dependencies {
implementation 'com.google.android.material:material:1.0.0'
implementation 'de.hdodenhof:circleimageview:2.1.0'
implementation 'androidx.appcompat:appcompat:1.3.0'
implementation 'com.google.android.material:material:1.4.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
}
這裡添加了兩行依賴關係,第一行就是Design Support庫,第二行是一個開源項目CircleImageView,它可以用來輕鬆實現圖片圓形化的功能,我們待會就會用到它。CircleImageView的項目主頁地址是:https://github.com/hdodenhof/CircleImageView。
在開始使用NavigationView之前,我們還需要提前準備好兩個東西:menu和headerLayout。menu是用來在NavigationView中顯示具體的菜單項的,headerLayout則是用來在NavigationView中顯示頭部佈局的。
我們先來準備menu,這裡我事先找了幾張圖片來作為按鈕的圖標,並將它們放在了drawable-xxhdpi目錄下。然後右擊menu文件夾→New→Menuresource file,創建一個nav_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_call"
android:icon="@drawable/nav_call"
android:title="Call" />
<item
android:id="@+id/nav_friends"
android:icon="@drawable/nav_friends"
android:title="Friends"/>
<item
android:id="@+id/nav_location"
android:icon="@drawable/nav_location"
android:title="Location"/>
<item
android:id="@+id/nav_mail"
android:icon="@drawable/nav_mail"
android:title="Mail"/>
<item
android:id="@+id/nav_task"
android:icon="@drawable/nav_tasks"
android:title="Tasks"/>
</group>
</menu>
首先在