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 线上教室,脸书粉丝团,会不定期发布相关资讯,不想错过最新资讯,不要忘记来按赞,追踪喔!也欢迎大家将这篇文章分享给更多人喔。

我们明天再见罗!!!掰掰~


<<:  css visibility

>>:  [Day21] Tableau 轻松学 - Parameter

LeetCode解题 Day18

282. Expression Add Operators https://leetcode.com...

资料管理能力成熟度模型(DCMM)

资料管理能力成熟度模型(Data Management Capability Maturity Mo...

【领域展开 21 式】 Menu 修炼持续进行中

继续大战 Menu day2 再怎样都要把 Sample 的页面浏览完成,才能知道要选哪些页面吧!徒...

05 | WordPress 标题区块 Heading Block

透过 WordPress 区块编辑器撰写文章最常用的「区块 Block」之一,就是「标题区块 He...

Day 37 - 在 AWS Lambda 建立 OpenCV Layer

Day 37 - 在 AWS Lambda 建立 OpenCV Layer 因为 OpenCV 在影...