You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kotlin实现动态Checkbox选中配料数据跨Activity传递

实现选中配料获取与跨Activity传递的解决方案

1. 改造Adapter,维护选中状态并提供获取选中项的方法

首先需要在Adapter中跟踪用户的选中状态,给Checkbox添加点击监听,并提供方法返回选中的配料数据:

class AdapterTopping(val listTopping: List<DataItem?>) : RecyclerView.Adapter<AdapterTopping.MyViewHolder>() {
    // 存储选中的配料对象
    private val selectedToppings = mutableListOf<DataItem>()

    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 topping = listTopping[position] ?: return
        
        holder.checkbox.text = topping.attributes?.name
        // 初始化Checkbox选中状态
        holder.checkbox.isChecked = selectedToppings.contains(topping)

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

        // 监听Checkbox状态变化
        holder.checkbox.setOnCheckedChangeListener { _, isChecked ->
            if (isChecked) {
                selectedToppings.add(topping)
            } else {
                selectedToppings.remove(topping)
            }
        }
    }

    // 提供外部获取选中配料的方法
    fun getSelectedToppings(): List<DataItem> {
        return selectedToppings.filterNotNull()
    }
}

2. 让DataItem实现Parcelable接口

要跨Activity传递对象列表,DataItem必须实现Parcelable接口。如果是API生成的数据类,修改如下:

@Parcelize
data class DataItem(
    val id: Int?,
    val attributes: Attributes?
) : Parcelable

@Parcelize
data class Attributes(
    val name: String?,
    val price: Int?
) : Parcelable

注意:需要在app模块的build.gradle中添加kotlin-parcelize插件:

plugins {
    id 'com.android.application'
    id 'org.jetbrains.kotlin.android'
    id 'kotlin-parcelize' // 添加此行
}

3. 在Detail Activity中获取选中数据并传递

修改Detail Activity代码,保存Adapter实例,点击下单按钮时获取选中数据并通过Intent传递:

// 将adapterTopping提升为全局变量
private lateinit var adapterTopping: AdapterTopping

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_detail)

    val btn_pesan = findViewById<AppCompatButton>(R.id.btn_pesan)
    btn_pesan.setOnClickListener {
        // 获取选中的配料
        val selectedToppings = adapterTopping.getSelectedToppings()
        if (selectedToppings.isNotEmpty()) {
            val intent = Intent(this, CheckoutActivity::class.java)
            // 传递Parcelable类型的列表
            intent.putParcelableArrayListExtra("SELECTED_TOPPINGS", ArrayList(selectedToppings))
            startActivity(intent)
            finish()
        } else {
            Toast.makeText(this, "请选择至少一种配料", Toast.LENGTH_SHORT).show()
        }
    }

    ApiConfigFood.getService().getToppings(id).enqueue(object : Callback<ResponseFoods> {
        override fun onResponse(call: Call<ResponseFoods>, response: Response<ResponseFoods>) {
            if (response.isSuccessful) {
                val responseList = response.body()?.data?.filterNotNull() ?: emptyList()
                if (responseList.isNotEmpty()) {
                    adapterTopping = AdapterTopping(responseList)
                    rv_topping.apply {
                        layoutManager = LinearLayoutManager(this@DetailActivity)
                        setHasFixedSize(true)
                        adapter = adapterTopping
                    }
                } else {
                    // 无数据处理逻辑
                }
            } else {
                // 请求失败处理逻辑
            }
        }

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

4. 在Checkout Activity中接收并展示选中配料

先创建一个用于展示选中配料的简单Adapter:

class CheckoutToppingAdapter(val listTopping: List<DataItem>) : RecyclerView.Adapter<CheckoutToppingAdapter.MyViewHolder>() {
    class MyViewHolder(view: View) : RecyclerView.ViewHolder(view) {
        val tvToppingName = view.findViewById<TextView>(R.id.tv_topping_name)
        val tvToppingPrice = view.findViewById<TextView>(R.id.tv_topping_price)
    }

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

    override fun getItemCount(): Int = listTopping.size

    override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
        val topping = listTopping[position]
        holder.tvToppingName.text = topping.attributes?.name
        
        val price = topping.attributes?.price
        val localID = Locale("in", "ID")
        val numberFormat = NumberFormat.getCurrencyInstance(localID)
        numberFormat.minimumFractionDigits = 0
        holder.tvToppingPrice.text = numberFormat.format(price)
    }
}

然后在Checkout Activity中接收数据并设置展示:

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_checkout)

    // 获取传递过来的选中配料列表
    val selectedToppings = intent.getParcelableArrayListExtra<DataItem>("SELECTED_TOPPINGS") ?: emptyList()
    
    val rvCheckoutTopping = findViewById<RecyclerView>(R.id.rv_checkout_topping)
    rvCheckoutTopping.apply {
        layoutManager = LinearLayoutManager(this@CheckoutActivity)
        setHasFixedSize(true)
        adapter = CheckoutToppingAdapter(selectedToppings)
    }
}

内容的提问来源于stack exchange,提问作者Chishiya

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 17:07:57