从 Kotlin 中的动态复选框获取数据列表

问题描述 投票:0回答:1

需要帮助。我想从动态复选框中获取有关浇头的数据。当用户单击订购按钮时,我希望将复选框中选中的数据发送到另一个活动。如下图所示

来自详细活动:

结帐活动:

我在 Detail Activity 上使用 ryclerview 得到了排名靠前的列表,所以复选框表明数据是动态的。

这是我的适配器:

class AdapterTopping(val listTopping: List<DataItem?>?) : RecyclerView.Adapter<AdapterTopping.MyViewHolder>() {
    class MyViewHolder(view : View) : RecyclerView.ViewHolder(view){
        val checkbox = view.findViewById<CheckBox>(R.id.ch_box)
        val price_topping = view.findViewById<TextView>(R.id.tv_price_topping)
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
        val view = LayoutInflater.from(parent.context).inflate(R.layout.item_topping,parent,false)
        return MyViewHolder(view)
    }

    override fun getItemCount(): Int {
        if (listTopping != null){
            return listTopping.size
        }
        return 0
    }

    override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
        
        holder.checkbox.text = listTopping?.get(position)?.attributes?.name

        val priceTopping = listTopping?.get(position)?.attributes?.price
        val localID = Locale("in", "ID")
        val numberFormat = NumberFormat.getCurrencyInstance(localID)
        numberFormat.minimumFractionDigits = 0
        holder.price_topping.text = numberFormat.format(priceTopping)

    }
}

这是我的详细活动:

val btn_pesan = findViewById<AppCompatButton>(R.id.btn_pesan)
        btn_pesan.setOnClickListener {
            val intent = Intent(it.context,CheckoutActivity::class.java)
            startActivity(intent)
            finish()
        }
        
        ApiConfigFood.getService().getToppings(id).enqueue(object : Callback<ResponseFoods>{
            override fun onResponse(call: Call<ResponseFoods>, response: Response<ResponseFoods>) {
                if (response.isSuccessful){
                    if (response.body()?.data?.isNotEmpty() == true){
                        val responseBody = response.body()
                        val responseList = responseBody?.data
                        val adapterTopping = AdapterTopping(responseList)
                        rv_topping.apply {
                            layoutManager = LinearLayoutManager(this@DetailActivity)
                            setHasFixedSize(true)
                            adapterTopping.notifyDataSetChanged()
                            adapter = adapterTopping
                        }
                    }
                    else{
                        // not found data
                    }
                }
                else{
                    // not found data
                }
            }

            override fun onFailure(call: Call<ResponseFoods>, t: Throwable) {
                // error server
                Toast.makeText(this@DetailActivity, t.localizedMessage, Toast.LENGTH_SHORT).show()
            }

        })

Textview 的浇头列表如下图:

android kotlin checkbox checkboxlist
1个回答
0
投票

首先,您应该使您的列表类型不可为空,并且您的列表本身不可为空,这样您就不必在整个代码中进行空检查:

class AdapterTopping(val listTopping: List<DataItem>) : //...

有两种方法可以使复选框在适配器中工作:

1。简单但不稳健的方式

为您的 DataItem 类提供一个可变属性:

var isChecked = false
。在
onBindViewHolder
中,使用此属性更新复选框状态,并为复选框提供更新此值的侦听器。由于 DataItem 类具有此属性,您可以检查列表内容以确定将哪些项目作为检查成分传递到下一个屏幕。

class AdapterTopping(val listTopping: List<DataItem>) : RecyclerView.Adapter<AdapterTopping.MyViewHolder>() {
    class MyViewHolder(view : View) : RecyclerView.ViewHolder(view){
        val checkbox = view.findViewById<CheckBox>(R.id.ch_box)
        val price_topping = view.findViewById<TextView>(R.id.tv_price_topping)
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
        val view = LayoutInflater.from(parent.context).inflate(R.layout.item_topping,parent,false)
        return MyViewHolder(view)
    }

    override fun getItemCount(): Int = listTopping.size

    override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
        val item = listTopping[position]
        
        holder.checkbox.apply {
            text = item.attributes.name
            isChecked = item.isChecked
            setOnCheckedChangeListener { _, isChecked -> item.isChecked = isChecked }
        }

        val priceTopping = item.attributes.price
        val localID = Locale("in", "ID")
        val numberFormat = NumberFormat.getCurrencyInstance(localID)
        numberFormat.minimumFractionDigits = 0
        holder.price_topping.text = numberFormat.format(priceTopping)

    }
}

这不健壮的原因是您现在在类之间传递可变类实例,在一个类中更改它们并读取另一个类中的更改。这违反了单一职责原则,并可能导致“意大利面条代码”。由于您没有很好地封装功能,因此在更改代码时很容易引入错误。

2。冗长但健壮的方式

adapter 的list 属性是可变的,但是DataItem 类是不可变的。当一个项目被选中时,适配器会公开一个回调,它会调用复选框的更改侦听器。 Activity 或 Fragment 有责任使用此回调创建一个新的 DataItems 列表并进行适当的更改。然后它将这个列表传递回适配器。

使用常规适配器正确执行此操作非常难看。您应该使用 ListAdapter 来完成。您可以查找有关如何使用 ListAdapter 的教程。

总结

首先,我认为您可以使用第一种方式,直到您非常牢固地掌握适配器工作原理的概念。在这种情况下,它并没有那么糟糕,因为传递给适配器的项目列表永远不需要更改长度(因为它只是一个固定的成分列表)。

要使复选框在适配器中工作,您必须为它们提供一个点击侦听器,该侦听器会触发 Activity 或 Fragment 可以响应的回调。在那个回调中,

© www.soinside.com 2019 - 2024. All rights reserved.