Android Kotlin 多选下拉菜单

Posted

技术标签:

【中文标题】Android Kotlin 多选下拉菜单【英文标题】:Android Kotlin Multiselect dropdown 【发布时间】:2022-01-22 04:02:05 【问题描述】:

我想实现一个多选下拉菜单,如下图所示,箭头在末尾,所选项目显示在文本字段中(如果需要,可以选框)。有人可以帮忙吗? 我不希望它像对话框一样弹出,而是像普通微调器一样在 textview 下打开。

multi select

【问题讨论】:

【参考方案1】:

您必须在自己的 xml 中创建一个微调器,并为该微调器创建一个自定义适配器,该适配器将一个数组作为参数

你可以关注这些

Multi Select Spinner - GitHub Repo

Multiselect Spinner

Step by step development of MultiselectSpinner

【讨论】:

虽然这些链接可能会回答问题,但最好在此处包含答案的基本部分并提供链接以供参考。如果链接页面发生更改,仅链接的答案可能会失效。 感谢您的回答,您提供的链接将“多选微调器”显示为弹出对话框。你知道打开普通下拉微调器的其他方法吗?【参考方案2】:

您可以查看谷歌官方文档 - https://material.io/components/menus/android

将项目添加到菜单后,在其中添加一个可绘制图标。

【讨论】:

我不确定是否可以在菜单中选择多个选项。有没有办法做到这一点?【参考方案3】:

以自定义方式处理所选项目视图的可见性。

我对 Spinner Adapter 进行了一些更改以处理多项选择,请尝试以下代码:

微调器适配器 (MultiSelectionSpinnerAdapter.kt)

class MultiSelectionSpinnerAdapter(var context: Context?, var spinnerList: List<String>?, val multipleSelectionCallBack:MultipleSelectionCallBack) : BaseAdapter() 

    private var TAG = MultiSelectionSpinnerAdapter::class.java.simpleName
    private var selectedItemsList: ArrayList<String> = ArrayList()
    fun setSelectedItemsList(selectedItemsList: ArrayList<String>) 
        this.selectedItemsList = selectedItemsList
        notifyDataSetChanged()
    
    private val inflater: LayoutInflater = context!!.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater

    override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View 

        val view: View
        val vh: ItemHolder
        if (convertView == null) 
            view = inflater.inflate(R.layout.item_multi_selection_spinner, parent, false)
            vh = ItemHolder(view)
            view?.tag = vh
         else 
            view = convertView
            vh = view.tag as ItemHolder
        
        try 
            vh.tvSpinnerText.text = spinnerList!![position]
        catch (e:Exception)
            e.printStackTrace()
        

        if (selectedItemsList.size > 0) 
            for (i in selectedItemsList.indices) 
                if (selectedItemsList[i] == spinnerList!![position]) 
                    vh.llSpinnerSelected.visibility = View.VISIBLE
                    break
                else
                    vh.llSpinnerSelected.visibility = View.GONE
                
            
        

        view.setOnClickListener 
            val selectedItemText = spinnerList!![position]
            if(vh.llSpinnerSelected.visibility == View.VISIBLE)
                vh.llSpinnerSelected.visibility = View.GONE
                multipleSelectionCallBack.onItemSelect(false, selectedItemText, position)
            else
                vh.llSpinnerSelected.visibility = View.VISIBLE
                multipleSelectionCallBack.onItemSelect(true, selectedItemText, position)
            
        
        return view
    

    override fun getItem(position: Int): Any? 
        return spinnerList!![position]
    

    override fun getCount(): Int 
        return spinnerList!!.size
    

    override fun getItemId(position: Int): Long 
        return position.toLong()
    

    private class ItemHolder(row: View?) 
        val tvSpinnerText: TextView
        val llSpinnerSelected: LinearLayout

        init 
            tvSpinnerText = row?.findViewById(R.id.tvSpinnerText) as TextView
            llSpinnerSelected = row?.findViewById(R.id.llSpinnerSelected) as LinearLayout
            llSpinnerSelected.visibility = View.GONE
        
    

    interface MultipleSelectionCallBack
        fun onItemSelect(isSelect:Boolean, selectedItemText:String, position: Int)
    

微调器项目布局 (item_multi_selection_spinner.xml)

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_
    android:layout_
    android:padding="10dp">
    <TextView
        android:id="@+id/tvSpinnerText"
        android:layout_
        android:layout_
        android:layout_centerVertical="true"
        android:layout_toStartOf="@+id/llSpinnerSelected"
        android:textColor="@color/black"
        android:textSize="14sp"/>
    <LinearLayout
        android:id="@+id/llSpinnerSelected"
        android:layout_
        android:layout_
        android:padding="10dp"
        android:layout_alignParentEnd="true"
        android:layout_centerVertical="true">
        <ImageView
            android:layout_
            android:layout_
            android:src="@drawable/bg_selected_item"/>
    </LinearLayout>
</RelativeLayout>

活动代码:

class YourActivityName : AppCompatActivity(),
    MultiSelectionSpinnerAdapter.MultipleSelectionCallBack 
    val items = ArrayList<String>()
    lateinit var multiSpinner:Spinner
    lateinit var  multiSelectionSpinnerAdapter : MultiSelectionSpinnerAdapter
    private var selectedItemsList: java.util.ArrayList<String> = java.util.ArrayList()
    override fun onCreate(savedInstanceState: Bundle?) 
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_name)
        multiSpinner = findViewById<View>(R.id.multiSpinner) as Spinner

        items.add("A")
        items.add("B")
        items.add("C")
        items.add("D")
        items.add("E")
        multiSelectionSpinnerAdapter = MultiSelectionSpinnerAdapter(this, items, this)
        multiSpinner.adapter = multiSelectionSpinnerAdapter
    
    override fun onItemSelect(isSelect: Boolean, selectedItemText: String, position: Int) 
        if(isSelect)
            //Add object to your selected list
        else
            //remove object from your selected list
        
        Log.e("onItemSelect----","-=:$selectedItemsList.size")
        multiSelectionSpinnerAdapter.setSelectedItemsList(selectedItemsList)
    

您可以在onItemSelect()方法中根据您的要求处理数据

多个选定微调器的输出是:

【讨论】:

以上是关于Android Kotlin 多选下拉菜单的主要内容,如果未能解决你的问题,请参考以下文章

swift 3中的多选下拉菜单

使用 JavaScript 清除多选下拉菜单

Select2多选下拉菜单导致窗口滚动

Android自定义下拉/弹出菜单

基于第一个下拉菜单的引导多选动态选项

带有xeditable的Angular js中的多选下拉菜单