站長留言

  • ✅ 本站維護及更新歷史紀錄,詳情請參考公告
  • ✅ 有任何意見、想法,歡迎留言給Spicy知道喔
  • ✅ 固定於每周一至周五更新Blogger文章,周末不定期
程式Android 安卓

【APP/Android】如何製作側邊選單:Navigation Drawer (DrawerLayout),並和 Toolbar整合

tags: APP Android

步驟1:在 View 加入 Navigation Drawer

  • Navigation Drawer 的程式碼分為兩個部分:
    • 主畫面:平常我們在用的畫面
    • 側邊選單
  • NavigationView 的 width:建議用dp設定,且不超過320dp
<?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:id="@+id/drawerLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:context=".MiaoliActivity">

    <!--主畫面-->
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/colorLight"
        android:orientation="vertical">
    ...
    </LinearLayout>
    
    <!--側邊選單-->
    <!--headerLayout:於側邊選單中的上方加入圖片、文字...-->
    <android.support.design.widget.NavigationView
        android:id="@+id/nav_view"
        android:layout_width="240dp"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:fitsSystemWindows="true"
        app:menu="@menu/activity_miaoli_menu" 
        app:headerLayout="@layout/header_miaoli"/>

</android.support.v4.widget.DrawerLayout>
  • 屬性介紹:
    • fitsSystemWindows:若為true,則內容從 status bar 下方才開始呈現

    • app:menu:側邊選單的資料

    • app:headerLayout:側邊選單中的上方圖片、文字,這個功能可加、可不加連結

步驟2:設置 Navigation Drawer 的 menu

  • 於 res/menu 創建一個 activity_miaoli_menu
<?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/home"
            android:checked="true"
            android:icon="@mipmap/ic_menu_home"
            android:title="@string/home" />
        <item
            android:id="@+id/miaoli"
            android:title="@string/miaoli"/>
        <item
            android:id="@+id/taichung"
            android:title="@string/taichung"/>
    </group>
</menu>
  • 屬性介紹:
    • checkableBehavior:若為single,則設定為單選
    • checked:預設的選取項目

步驟3:在後端 Java class 實作 Navigation Drawer

@Override
protected void onCreate(Bundle savedInstanceState) {
    ...
    DrawerLayout drawerLayout = (DrawerLayout) findViewById(R.id.drawerLayout);
    NavigationView navigationView = (NavigationView) findViewById(R.id.nav_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.home) {
                // 按下「首頁」要做的事
                ...
                return true;
            }
            else if (id == R.id.miaoli) {
                // 按下「使用說明」要做的事
                ...
                return true;
            }
            ...
            return false;
        }
    });
}

補充1:Navigation Drawer 與 Toolbar 整合

@Override
protected void onCreate(Bundle savedInstanceState) {
    ...
    DrawerLayout drawerLayout = (DrawerLayout) findViewById(R.id.drawerLayout);
    NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    // 用toolbar做為APP的ActionBar
    setSupportActionBar(toolbar);
    
    // 將drawerLayout和toolbar整合,會出現「三」按鈕
    ActionBarDrawerToggle actionBarDrawerToggle = new ActionBarDrawerToggle(this, 
        drawerLayout, toolbar, R.string.open, R.string.close);
    drawerLayout.addDrawerListener(actionBarDrawerToggle); 
    actionBarDrawerToggle.syncState();
}

補充2:選用功能 app:headerLayout

  • 於 res/layout 創建一個 Layout:header_miaoli.xml
  • 設計自己想要呈現的 header
<?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">

    <ImageView
        android:layout_width="64dp"
        android:layout_height="64dp"
        android:contentDescription="@null"
        android:src="@drawable/welcome_pic" />

    <TextView
        android:id="@+id/txtHeader"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:ellipsize="end"
        android:paddingTop="4dp"
        android:text="example"
        android:textColor="#ffffff" />

</LinearLayout>
  • 屬性介紹:
    • ellipsize:當字符內容太長顯示不下時可以省略號代替未顯示的字符;省略號可以在顯示區域的起始、中間、結束位置,或者以跑馬燈的方式顯示文字
      • android:ellipsize="start"
      • android:ellipsize="middle"
      • android:ellipsize="end"
      • android:ellipsize="marquee"

Reference 參考資料

  1. Day 18 - 側滑選單DrawerLayout:https://ithelp.ithome.com.tw/articles/10188283
  2. android:ellipsize省略文字用法:http://zhangkun716717-126-com.iteye.com/blog/864989
  3. nav-drawer 官方文件:
    https://developer.android.com/training/implementing-navigation/nav-drawer.html

Extension 延伸閱讀

  1. DrawerLayout和NavigationView使用详解:https://www.jianshu.com/p/d2b1689a23bf
  2. [Andriod Studio] 簡單實作 DrawerLayout 側邊菜單及如何使用自己畫的菜單:https://dotblogs.com.tw/starhao/2016/10/06/083648
  3. why method setDrawerListener is deprecated?how to resolve it?
    https://stackoverflow.com/questions/37629823/why-method-setdrawerlistener-is-deprecatedhow-to-resolve-it

沒有留言:

張貼留言

本網站建議使用電腦或平板瀏覽