iT邦幫忙

2021 iThome 鐵人賽

DAY 22
0
Mobile Development

Android 口罩地圖入門實戰 30 天 (使用 Kotlin 程式語言)系列 第 22

Day 22:Spinner 下拉選單結合縣市鄉鎮小工具

本篇文章同步發表在 HKT 線上教室 部落格,線上影音教學課程已上架至 UdemyYoutube 頻道。另外,想追蹤更多相關技術資訊,歡迎到 臉書粉絲專頁 按讚追蹤喔~

程式碼範例

範例名稱:Spinner 下拉選單結合縣市鄉鎮小工具
開發人員:HKT (侯光燦)
程式語言:Kotlin
開發環境:Android Studio 4.1.2 & Android 11 & Kotlin 1.4.30
授權範圍:使用時必須註明出處且不得為商業目的之使用
範例下載點:點我下載

今天 ,我們將要介紹,如何使用 Spinner 下拉選單元件,結合縣市鄉鎮資料。列表資料將根據我們當下選擇的縣市鄉鎮,從全台灣藥局資料中,透過 Kotlin 的 Collection 語法過濾顯示出我們選擇的縣市與鄉鎮區域的庫存口罩資料。

縣市、鄉鎮下拉選單與藥局詳細資訊頁的 Wireframe

畫面佈局加入兩個 Spinner

在 activity_main.xml 加入兩個 Spinner,第一個 Spinner 用途為選擇縣市選單,另一個 Spinner 會根據前面選擇的縣市,呈現對應所屬的鄉鎮選單。

<androidx.constraintlayout.widget.ConstraintLayout
    android:id="@+id/layout_spinner"
    android:layout_width="match_parent"
    android:layout_height="100dp"
    app:layout_constraintBottom_toTopOf="@+id/recycler_view"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constraintTop_toTopOf="parent">

    <Spinner
        android:id="@+id/spinner_county"
        android:layout_width="150dp"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toLeftOf="@+id/spinnerTown"
        app:layout_constraintTop_toTopOf="parent" />

    <Spinner
        android:id="@+id/spinner_town"
        android:layout_width="150dp"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toRightOf="@+id/spinner_county"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

Spinner 資料來源與連動設定

在 MainActivity.kt 加入兩個 Spinner 資料來源與監聽選擇處理事件

private fun initView() {
        val adapterCounty = ArrayAdapter(
            this,
            android.R.layout.simple_spinner_dropdown_item,
            CountyUtil.getAllCountiesName()
        )
        binding.spinnerCounty.adapter = adapterCounty
        
        //監聽「縣市」下拉選單選擇
        binding.spinnerCounty.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
            override fun onItemSelected(
                parent: AdapterView<*>?,
                view: View?,
                position: Int,
                id: Long
            ) {
                currentCounty = binding.spinnerCounty.selectedItem.toString()
                setSpinnerTown()
            }

            override fun onNothingSelected(parent: AdapterView<*>?) {

            }
        }

        //監聽「鄉鎮」下拉選單選擇
        binding.spinnerTown.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
            override fun onItemSelected(
                parent: AdapterView<*>?,
                view: View?,
                position: Int,
                id: Long
            ) {
                currentTown = binding.spinnerTown.selectedItem.toString()
                if (pharmacyInfo != null) {
                    updateRecyclerView()
                }
            }

            override fun onNothingSelected(parent: AdapterView<*>?) {

            }
        }

        //設定初始預設縣市、鄉鎮資料
        setDefaultCountyWithTown()
        
        ...
        ...
        ...
}       

設定縣市連動鄉鎮選單

在 MainActivity.kt 加入縣市連動鄉鎮選單

  private fun setSpinnerTown() {
        val adapterTown = ArrayAdapter(
            this,
            android.R.layout.simple_spinner_dropdown_item,
            CountyUtil.getTownsByCountyName(currentCounty)
        )
        binding.spinnerTown.adapter = adapterTown
        binding.spinnerTown.setSelection(CountyUtil.getTownIndexByName(currentCounty, currentTown))
    }

預設縣市鄉鎮選單

在 MainActivity.kt 加入預設縣市鄉鎮選單

//預設名稱
private var currentCounty: String = "臺東縣"
private var currentTown: String = "池上鄉"
...
...    
...    
private fun setDefaultCountyWithTown() {
   binding.spinnerCounty.setSelection(CountyUtil.getCountyIndexByName(currentCounty))
   setSpinnerTown()
}

擴充縣市鄉鎮小工具

因為想要讓 Spinner 選單,可以有初值縣市鄉鎮設定,所以在 CountyUtil.kt 加入獲取索引值的方法

    /**
     * 獲取縣市索引值
     * @return 返回縣市索引值
     */
    fun getCountyIndexByName(countyName:String): Int {
        return counties.indexOf(countyName)
    }

    /**
     * 獲取鄉鎮索引值
     * @return 返回鄉鎮索引值
     */
    fun getTownIndexByName(countyName:String,townName:String): Int {
        val index = counties.indexOf(countyName)
        return towns[index].indexOf(townName)
    }

更新列表資料

在 MainActivity.kt 加入根據 Spinner 縣市鄉鎮選單顯示對應列表資料

private var pharmacyInfo: PharmacyInfo? = null
...
...
...

private fun updateRecyclerView() {

    val filterData =
        pharmacyInfo?.features?.filter {
            it.properties.county == currentCounty && it.properties.town == currentTown
        }

    if (filterData != null) {
        viewAdapter.pharmacyList = filterData
    }
}

輸出結果

參考資料

HKT 線上教室
https://tw-hkt.blogspot.com/

Freepik
https://www.freepik.com/


那今天【iThome 鐵人賽】就介紹到這邊囉~

順帶一提,KT 線上教室,臉書粉絲團,會不定期發佈相關資訊,不想錯過最新資訊,不要忘記來按讚,追蹤喔!也歡迎大家將這篇文章分享給更多人喔。

我們明天再見囉!!!掰掰~


上一篇
Day 21:Spinner 下拉選單基本用法
下一篇
Day 23:獲取位置權限
系列文
Android 口罩地圖入門實戰 30 天 (使用 Kotlin 程式語言)30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言