【问题标题】:Two Spinners Populated By Same ArrayList由相同 ArrayList 填充的两个微调器
【发布时间】:2021-11-20 19:13:43
【问题描述】:

所以我试图在同一个片段中填充两个 Spinner,两者都使用相同的列表,但显示不同的项目。

我有以下数据类:

data class ProductTypeObject (

    //ProductType fields (2 fields)
    var productType: String = "",
    var productGroup: String = "",

    @ServerTimestamp
    var dateEditedTimestamp: Date? = null,

    @Exclude @set:Exclude @get:Exclude
    var productTypeID: String = ""

) : Serializable {

    override fun toString(): String {
        return productType
    }
   
}

当从 ViewModel 观察列表时,Spinner 填充在 Fragment 中,如下所示:

        // Observe ProductTypes and populate Spinner
        businessViewModel.allAppDataProductTypes.observe(viewLifecycleOwner, Observer { productTypeArrayList ->
            if (!productTypeArrayList.isNullOrEmpty()){
                val adapter = ArrayAdapter(requireContext(), android.R.layout.simple_spinner_item, productTypeArrayList)
                binding.inventoryAddEditProductGroupSpinner.adapter = adapter
            }
        })

这显示了product types as I have specified this in the toString()of the object, but is there a way to direct a second Spinner to show a list ofproduct group 的列表?

【问题讨论】:

    标签: kotlin arraylist android-arrayadapter android-spinner


    【解决方案1】:

    如果您不需要从微调器中检索值,最简单的方法是将值映射到新列表:

    businessViewModel.allAppDataProductTypes.observe(viewLifecycleOwner, Observer { productTypeArrayList ->
        if (!productTypeArrayList.isNullOrEmpty()){
            //...
    
            val adapter2 = ArrayAdapter(requireContext(), android.R.layout.simple_spinner_item, 
                productTypeArrayList.map(ProductTypeObject::productGroup)
            //...
        }
    })
    

    如果您需要两个 Spinner 都能够检索原始项目类型,那么您不能按原样使用 ArrayAdapter 类,因为它完全依赖于您的类的 toString()。您可以像这样子类化它以获得更灵活的版本,让您传递使用的属性或 lambda,而不是 toString()。我没有测试它,但我认为它会做你想要的。如果你使用这个类,你不需要在你的原始数据类中覆盖toString()

    class CustomArrayAdapter<T : Any>(
        context: Context,
        items: List<T>,
        val itemToCharSequence: T.() -> CharSequence = Any::toString
    ) : ArrayAdapter<T>(context, 0, items) {
        
        private val inflater = LayoutInflater.from(context)
        
        override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
            return (convertView ?: inflater.inflate(android.R.layout.simple_spinner_item, parent, false))
                .apply {
                    val item = getItem(position)!! // will never be null inside getView()
                    (this as TextView).text = itemToCharSequence(item)
                }
        }
    }
    

    用法:

    val typeAdapter = CustomArrayAdapter(requireContext(), productTypeArrayList, ProductTypeObject::productType)
    val groupAdapter = CustomArrayAdapter(requireContext(), productTypeArrayList, ProductTypeObject::productGroup)
    

    【讨论】:

    • 许多坦克 Tenfour04 - 一些有趣的选项。我可能需要在我的应用程序中进一步使用其中一个或两个,但我可能会在这种情况下创建一个单独的数据类和列表并访问 toString()。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-11
    • 2012-06-28
    相关资源
    最近更新 更多