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
相关产品推荐
相关产品推荐

