iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 19
0
Mobile Development

大一之 Android Kotlin 自習心路歷程系列 第 19

[Day 19] Android in Kotlin: Naigation Drawer 分享

  • 分享至 

  • xImage
  •  

以下出現之部份畫面為參照 FieC 公司開發的 “Ahorro” 所仿造出來的,該創意全為該公司所有,且本文之全部內容皆與其公司無任何直接關係。

Ahorro - 輕鬆記帳,簡單理財

實作出左滑頁面

有用過 Android 的手機都會看過這個畫面:透過左滑或右滑顯示出更多選項,在 android 開發中可以透過 Navigation Drawer 實現。
android default drawer activity

這是在 New -> Activity -> Navigation Drawer Activity 可以直接建立的範例。

想要自己製作的話,會需要

  • 建立 menu
  • 拉 layout
  • 建立 activity
  • 建立點擊事件

我的暑假作業中完成品是這樣
my drawer

Menu

menu screen shot
在 res 的資料夾底下自己新增名為 menu 的資料夾並新增 menu 檔。

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">

    <item
        android:id="@+id/item_main_expense"
        android:title="支出"
        android:icon="@drawable/ic_baseline_money_off_24_gray"/>
    <item
        android:id="@+id/item_main_income"
        android:icon="@drawable/ic_baseline_attach_money_24_gray"
        android:title="收入"/>
    <item
        android:id="@+id/item_main_analysis"
        android:icon="@drawable/ic_baseline_bar_chart_24_gray"
        android:title="分析"/>
    <item
        android:id="@+id/item_main_settings"
        android:title="設定"
        android:icon="@drawable/ic_baseline_settings_24_gray"/>
</menu>

<item/> 放在 <menu></menu> 裡面,每一個 item 就代表多少個項目。
每一個ㄖitem 一定要有 title 跟 id 的屬性才能使用。至於 icon 就是用來顯示圖示的。
也可以加上 <group> </group> 做分類

menu 做好了以後就讓 drawer layout 使用

在我的這個作品裡面,主畫面的佈局構造是這樣的

<androidx.constraintlayout.widget.ConstraintLayout>

    <androidx.appcompat.widget.Toolbar/>
    
    <androidx.drawerlayout.widget.DrawerLayout>
        <fragment/>
        <com.google.android.material.navigation.NavigationView/>
   </androidx.drawerlayout.widget.DrawerLayout>
   
</androidx.constraintlayout.widget.ConstraintLayout>

Toolbar 放在這個 xml 給 activity 用,好對 navigation drawer 做動作
要顯示的畫面塞進 fragment,當監聽到 drawer 上的 item 被點擊時,替換掉 fragment 就好了。
Navigation view 則是放抽屜的畫面。

跟範例裡面不一樣的地方是:我的 drawer layout 沒有蓋過 toolbar,是否覆蓋取決於你的佈局。

比較需要注意的是,要記得在最外圈的 layout 加上
android:fitsSystemWindows="true" 的屬性,否則 toolbar 會被 status bar 給蓋過去

最後在搭配自己寫好的 color 跟 style,drawer layout 的地方完成後成為這樣

<androidx.drawerlayout.widget.DrawerLayout
    android:id="@+id/layout_drawer"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_marginTop="?attr/actionBarSize"
    app:layout_constraintTop_toBottomOf="@id/toolbar_main"
    tools:openDrawer="left">
    <fragment
        android:id="@+id/main_fragment"
        android:layout_height="match_parent"
        android:name="com.example.accounting.main.MainPagerFragment"
        android:layout_width="match_parent"/>
    <com.google.android.material.navigation.NavigationView
        android:id="@+id/navigation_drawer"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start|left"
        android:elevation="5dp"
        app:itemBackground="@drawable/ahorro_navigation_drawer_item"
        app:menu="@menu/main_navigation_drawer"
        android:background="?attr/colorSecondary"
        android:fitsSystemWindows="true"/>
</androidx.drawerlayout.widget.DrawerLayout>

還有 toolbar 上的 navigation button 可以坐使用,一併放上。

<androidx.appcompat.widget.Toolbar
    android:id="@+id/toolbar_main"
    android:layout_width="match_parent"
    android:layout_height="?attr/actionBarSize"
    android:background="@color/AhorroActionBar_Gray"
    android:elevation="10dp"
    android:minHeight="?attr/actionBarSize"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintHorizontal_bias="0.0"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent"
    app:logo="@drawable/ic_round_monetization_on_24_white"
    app:navigationIcon="@drawable/ic_baseline_menu_24_white"
    app:title="@string/app_name"
    app:titleTextColor="#FFF" />

Drawer Activity

有了畫面以後就可以加上

val drawerLayout= findViewById<DrawerLayout>(R.id.layout_drawer)
val drawer: NavigationView= findViewById(R.id.navigation_drawer)
drawer.setNavigationItemSelectedListener {
    when(it.itemId){
        R.id.item_main_expense -> {
            setTheme(R.style.ExpenseTheme)
            transaction= supportFragmentManager.beginTransaction().apply {
                replace(R.id.main_fragment, frgExpense)
                commit()
            }
            drawerLayout.closeDrawer(drawer)
        }
        R.id.item_main_income -> {
            setTheme(R.style.IncomeTheme)
            transaction= supportFragmentManager.beginTransaction().apply {
                replace(R.id.main_fragment, frgIncome)
                commit()
            }
            drawerLayout.closeDrawer(drawer)
        }
        R.id.item_main_analysis -> {
            startActivity(Intent(this, PieChartActivity::class.java))
        }
        R.id.item_main_settings -> {
            startActivity(Intent(this, SettingActivity::class.java))
        }
        else -> {}
    }
    return@setNavigationItemSelectedListener true
}

用 setNavigationItemSelectedListener 監聽是哪一個 item 被點擊,再以其 id 去決定要開啟哪一個 activity 或是替換哪一個 fragment,道理跟 View.setOnClickListener 是一樣的。

最後在 toolbar 上加上 navigation button 讓 drawer 可以透過按鈕開開關關。

val toolbar= findViewById<Toolbar>(R.id.toolbar_main)
toolbar.inflateMenu(R.menu.main_toolbar)
toolbar.setNavigationOnClickListener {
    if (drawerLayout.isDrawerOpen(drawer)) {
        drawerLayout.closeDrawer(drawer)
    } else {
        drawerLayout.openDrawer(drawer)
    }
}

上一篇
[Day 18] Android in Kotlin: 基本的 Toolbar 使用分享
下一篇
[Day 20] Android in Kotlin: Theme 和 Style 的使用分享
系列文
大一之 Android Kotlin 自習心路歷程30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言