側滑選單是從螢幕左側滑出的元件,跟Menu一樣可以放一些功能或頁面連結,而側滑選單有較大的可用空間,當您有三個以上的選單項目時不妨考慮用側滑選單來做。
DrawerLayout也是Design Library提供的元件,在gradle加入這行
compile 'com.android.support:design:25.1.0'
修改activity_main.xml,將DrawerLayout擺在最外層,注意其特性是Layout內只能放兩個View,所以我們用一個Layout將主要內容包起來做為第一個View,第二個View即為選單本身
<?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/drawerLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- 頁面主要內容,用一個Layout包著 -->
<android.support.design.widget.CoordinatorLayout
android:id="@+id/coordinatorLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin">
<android.support.v7.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clipToPadding="false"
android:paddingBottom="72dp" />
<android.support.design.widget.FloatingActionButton
android:id="@+id/btnAdd"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="16dp"
android:src="@drawable/ic_add"
app:elevation="6dp"
app:pressedTranslationZ="12dp" />
</android.support.design.widget.CoordinatorLayout>
<!-- 選單 -->
<android.support.design.widget.NavigationView
android:id="@+id/navigation_view"
android:layout_width="240dp"
android:layout_gravity="start"
android:layout_height="match_parent"
app:menu="@menu/drawer" />
</android.support.v4.widget.DrawerLayout>
選單NavigationView是專為DrawerLayout搭配使用的元件,用app:menu
來設置選單要有那些項目,所以我們到menu資料夾新增一個drawer.xml,新增方式可參考Day17
<?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/action_home"
android:checked="true"
android:icon="@drawable/ic_pets"
android:title="首頁" />
<item
android:id="@+id/action_help"
android:icon="@drawable/ic_help"
android:title="使用說明" />
<item
android:id="@+id/action_settings"
android:icon="@drawable/ic_settings"
android:title="設定" />
<item
android:id="@+id/action_about"
android:icon="@drawable/ic_about"
android:title="關於" />
</group>
</menu>
選項用group包起來並將android:checkableBehavior
設置為單選,這樣NavigationView會自動處理點選時的上色效果,同時只會有一個選項被上色
執行APP,在畫面左邊按住並往右拖曳就會出現選單了,很神奇的是我們只放了白色的Icon,NavigationView會自動轉成平常顯示的灰色和選中時的藍色,真是好棒棒
要處理選項的點擊只要為NavigationView設置Listener就可以了
public class MainActivity extends AppCompatActivity {
private DrawerLayout drawerLayout;
private NavigationView navigation_view;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
drawerLayout = (DrawerLayout) findViewById(R.id.drawerLayout);
navigation_view = (NavigationView) findViewById(R.id.navigation_view);
// 為navigatin_view設置點擊事件
navigation_view.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
// 點選時收起選單
drawerLayout.closeDrawer(GravityCompat.START);
// 取得選項id
int id = item.getItemId();
// 依照id判斷點了哪個項目並做相應事件
if (id == R.id.action_home) {
// 按下「首頁」要做的事
Toast.makeText(MainActivity.this, "首頁", Toast.LENGTH_SHORT).show();
return true;
}
else if (id == R.id.action_help) {
// 按下「使用說明」要做的事
Toast.makeText(MainActivity.this, "使用說明", Toast.LENGTH_SHORT).show();
return true;
}
// 略..
return false;
}
});
}
要讓使用者有更好的體驗,我們要讓ActionBar出現一個「三」的按鈕,點擊時就滑出選單,並且讓選單不被ActionBar遮住
在style.xml裡修改theme,改成NoActionBar
修改activity_main,加上一個Toolbar元件,Toolbar比內建的ActionBar有更多功能,例如現在要做的與DrawerLayout整合即是
<?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/drawerLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- 頁面主要內容,用一個Layout包著 -->
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.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:elevation="4dp"/>
<android.support.design.widget.CoordinatorLayout
android:id="@+id/coordinatorLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@+id/toolbar"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin">
// 略..
</android.support.design.widget.CoordinatorLayout>
</RelativeLayout>
<!-- 選單 -->
<android.support.design.widget.NavigationView
android:id="@+id/navigation_view"
android:layout_width="240dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:menu="@menu/drawer"
app:headerLayout="@layout/navigation_header"/>
</android.support.v4.widget.DrawerLayout>
程式碼處設置Toolbar和DrawerLayout整合,就會出現「三」的按鈕了
public class MainActivity extends AppCompatActivity {
private DrawerLayout drawerLayout;
private NavigationView navigation_view;
private Toolbar toolbar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
drawerLayout = (DrawerLayout) findViewById(R.id.drawerLayout);
navigation_view = (NavigationView) findViewById(R.id.navigation_view);
toolbar = (Toolbar) findViewById(R.id.toolbar);
// 用toolbar做為APP的ActionBar
setSupportActionBar(toolbar);
// 將drawerLayout和toolbar整合,會出現「三」按鈕
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawerLayout, toolbar, R.string.drawer_open, R.string.drawer_close);
drawerLayout.addDrawerListener(toggle);
toggle.syncState();
// 下略...
}
當中的R.String.drawer_open是用來表示選單目前是開啟或關閉,要寫在string.xml裡
執行APP,左上角「三」的漢堡圖案點了就會滑出選單
NavigationView可以放自訂的header,只要建好header的xml並設置給NavigationView就可以了
在layout資料夾建立navigation_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="160dp"
android:background="@color/colorPrimary"
android:gravity="bottom"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin">
<ImageView
android:layout_width="64dp"
android:layout_height="64dp"
android:contentDescription="@null"
android:src="@drawable/ic_pets" />
<TextView
android:id="@+id/txtHeader"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:paddingTop="4dp"
android:text="唯一支持奶油臘腸"
android:textColor="#ffffff" />
</LinearLayout>
activity_main.xml中的NavigationView加上app:headerLayout
執行結果
若之後要透過程式修改Header內容:
// 取得Header
View header = navigation_view.getHeaderView(0);
// 取得Header中的TextView
TextView txtHeader = (TextView) header.findViewById(R.id.txtHeader);
txtHeader.setText("123");
Android 5.0之後可以在選單滑出時讓最上面的StatusBar變成半透明
values資料夾中新增styles(v21),已經有的就跳過
檔名為styles,選擇Version並按箭頭
Platform API Level輸入21,按OK
在styles(v21)加入兩個屬性
activity_main的最外層Layout加上android:fitSystemWindows
執行APP,選單滑出時最上面StatusBar會變成半透明的
DrawerLayout相對於單調的Menu會有比較好的擴充性和視覺效果,頁面比較多的APP如Gmail和Telegram都把側滑選單運用得很好,雖然建立時多了一點步驟但在多頁面切換時會是很好的選擇哦
今天的專案:https://github.com/IvanBean/Day18 ,裡面有Day13累積至今的內容可以參考