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

Android Kotlin:为RecyclerView添加第二个点击监听器(CheckBox事件)

为RecyclerView添加第二个点击监听器(CheckBox选中事件)

问题描述

我正在开发一个清单应用,已经实现了RecyclerView,每个列表项包含CheckBox和TextView。目前能处理TextView的点击事件,但无法响应CheckBox的选中/取消选中事件。数据存储在Firebase中没有问题,只是不知道如何在Adapter类中实现第二个点击监听器。


修改方案

1. 更新Adapter类

在Adapter构造函数中添加CheckBox的回调参数,并在ViewHolder中为CheckBox绑定选中状态变化监听:

package com.example.shoppinglist

import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.CheckBox
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView

class CheckListRecyclerViewAdapterClass (
    var checkList: List<CheckListModelClass>,
    private val itemClickListener: (CheckListModelClass) -> Unit,
    private val checkBoxClickListener: (CheckListModelClass, Boolean) -> Unit // 新增CheckBox回调
) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {

    var checkListTotalList: List<CheckListModelClass> = ArrayList()

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
        val myView = LayoutInflater.from(parent.context).inflate(R.layout.check_list_rec_view_model_layout, parent, false)
        return CheckListViewHolder(myView)
    }

    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
        (holder as CheckListViewHolder).bind(
            checkListTotalList[position],
            itemClickListener,
            checkBoxClickListener // 传入CheckBox回调
        )
    }

    override fun getItemCount(): Int {
        return checkListTotalList.size
    }

    fun submitList(checkList: List<CheckListModelClass>) {
        checkListTotalList = checkList
    }

    fun updateList(checkList: List<CheckListModelClass>) {
        checkListTotalList = checkList
        notifyDataSetChanged()
    }

    class CheckListViewHolder constructor(itemView: View) : RecyclerView.ViewHolder(itemView) {

        private val checkListCheckBox: CheckBox = itemView.findViewById(R.id.check_list_rec_view_model_layout_checkBox)
        private val checkListTextView: TextView = itemView.findViewById(R.id.check_list_rec_view_model_layout_textView)

        fun bind(
            checkListModelClass: CheckListModelClass,
            itemClickListener: (CheckListModelClass) -> Unit,
            checkBoxClickListener: (CheckListModelClass, Boolean) -> Unit
        ) {
            checkListTextView.text = checkListModelClass.checkListItemName
            checkListCheckBox.isChecked = checkListModelClass.checkListItemCheckListPosition

            // TextView点击事件
            checkListTextView.setOnClickListener { itemClickListener(checkListModelClass) }
            // CheckBox选中状态变化事件
            checkListCheckBox.setOnCheckedChangeListener { _, isChecked ->
                checkBoxClickListener(checkListModelClass, isChecked)
            }
        }
    }
}

2. 更新MainActivity

初始化Adapter时传入两个回调,并实现CheckBox状态变化后的Firebase数据同步:

package com.example.shoppinglist

import android.os.Bundle
import android.util.Log
import android.view.View
import android.view.inputmethod.EditorInfo
import android.view.inputmethod.InputMethodManager
import android.widget.EditText
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.google.firebase.firestore.CollectionReference
import com.google.firebase.firestore.FirebaseFirestore
import com.google.firebase.firestore.SetOptions

class MainActivity : AppCompatActivity() {

    private var checkListTotalListArray = ArrayList<CheckListModelClass>()
    private lateinit var checkListRecyclerViewAdapterClass: CheckListRecyclerViewAdapterClass
    private lateinit var checkListModelClass: CheckListModelClass
    private lateinit var addItemToListEditText: EditText
    private lateinit var firebaseFirestore: FirebaseFirestore
    private lateinit var collectionReference: CollectionReference

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

        firebaseFirestore = FirebaseFirestore.getInstance()
        collectionReference = firebaseFirestore.collection("shoppingList")
        checkListTotalListArray = arrayListOf()

        // 初始化Adapter时传入两个回调
        checkListRecyclerViewAdapterClass =
            CheckListRecyclerViewAdapterClass(checkListTotalListArray,
                { item -> checkListClickListener(item) },
                { item, isChecked -> checkBoxClickListener(item, isChecked) }
            )

        takeDataFromFireStore()

        // 配置RecyclerView
        val checkListRecyclerView = findViewById<RecyclerView>(R.id.check_list_recycler_view)
        checkListRecyclerView.layoutManager = LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false)
        checkListRecyclerView.adapter = checkListRecyclerViewAdapterClass

        addItemToListEditText = findViewById(R.id.check_list_fragment_item_enter_edit_text)
        addItemToListEditText.imeOptions = EditorInfo.IME_ACTION_DONE
        addItemToListEditText.isSingleLine = true
        addItemToList()
    }

    private fun checkListClickListener(checkListModelClass: CheckListModelClass) {
        Toast.makeText(this, "点击了条目: ${checkListModelClass.checkListItemName}", Toast.LENGTH_SHORT).show()
    }

    // 处理CheckBox状态变化,同步到Firebase
    private fun checkBoxClickListener(checkListModelClass: CheckListModelClass, isChecked: Boolean) {
        Toast.makeText(this, if(isChecked) "已选中: ${checkListModelClass.checkListItemName}" else "取消选中: ${checkListModelClass.checkListItemName}", Toast.LENGTH_SHORT).show()
        
        // 更新Firestore中的对应文档
        collectionReference.document(checkListModelClass.id)
            .set(mapOf("checkListItemCheckListPosition" to isChecked), SetOptions.merge())
            .addOnSuccessListener { Log.d("TAG", "CheckBox状态更新成功") }
            .addOnFailureListener { e -> Log.w("TAG", "更新CheckBox状态失败", e) }
    }

    private fun takeDataFromFireStore(){
        checkListTotalListArray.clear()
        collectionReference.get().addOnSuccessListener { documents ->
            if (!documents.isEmpty) {
                for (document in documents){
                    val item = document.toObject(CheckListModelClass::class.java)
                    item.id = document.id // 保存Firestore文档ID到模型类
                    checkListTotalListArray.add(item)
                }
                checkListRecyclerViewAdapterClass.submitList(checkListTotalListArray)
                checkListRecyclerViewAdapterClass.notifyDataSetChanged()
            }
        }.addOnFailureListener { exception ->
            Log.w("listen_data", "获取数据失败: ", exception)
        }
    }

    private fun saveDataToFireStore(){
        collectionReference.document()
            .set(checkListModelClass, SetOptions.merge())
            .addOnSuccessListener {
                takeDataFromFireStore()
                Log.d("TAG", "数据保存成功")
            }
            .addOnFailureListener { e -> Log.w("TAG", "数据保存失败", e) }
    }

    private fun addItemToList(){
        addItemToListEditText.onDone { addItemToListEditText.hideKeyboard() }
    }

    private fun View.hideKeyboard() {
        val inputMethodManager = context.getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager
        inputMethodManager.hideSoftInputFromWindow(windowToken, 0)
    }

    private fun EditText.onDone(callback: () -> Unit) {
        imeOptions = EditorInfo.IME_ACTION_DONE
        maxLines = 1
        setOnEditorActionListener { _, actionId, _ ->
            if (actionId == EditorInfo.IME_ACTION_DONE) {
                if(text.toString().isNotEmpty()) {
                    checkListModelClass = CheckListModelClass(false, text.toString())
                    saveDataToFireStore()
                    text.clear()
                }
                callback.invoke()
                true
            }
            false
        }
    }
}

3. 更新Model类

添加id字段,用于存储Firestore文档的唯一ID:

package com.example.shoppinglist

class CheckListModelClass(
   var id: String = "", // 新增文档ID字段
   var checkListItemCheckListPosition: Boolean = false,
   var checkListItemName: String = ""
)

关键说明

  • 通过新增回调参数,将CheckBox的状态变化事件传递到Activity中处理
  • Model类添加id字段是为了精准定位Firestore中的对应文档,确保状态更新正确
  • 使用setOnCheckedChangeListener监听CheckBox的选中状态变化,而非普通的点击事件

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 08:42:22