如何获取RecyclerView中当前选中项及CheckBox选中项的位置?
Hey there! Let's break down how to solve both of your questions using your existing TaskRecyclerAdapter and layout files.
Your adapter already has an OnItemClickListener set up to detect item clicks, but we can enhance it to track the currently selected position (useful for highlighting the selected item, for example) and make that position accessible externally.
Step 1: Update the Adapter to Track Selected Position
Modify TaskRecyclerAdapter.kt to add a variable for the selected position and update the click logic:
class TaskRecycleAdapter: RecyclerView.Adapter<TaskRecycleAdapter.MyViewHolder>() { private var list = emptyList<Data>() private lateinit var mListener : OnItemClickListener // Track the currently selected position (-1 means no item is selected) private var selectedPosition = -1 class MyViewHolder(binding: TaskHolderBinding, listener: OnItemClickListener): RecyclerView.ViewHolder(binding.root) { init { itemView.setOnClickListener { val clickedPosition = adapterPosition // Notify the listener of the click listener.onItemClick(clickedPosition) // Update the selected position and refresh affected items (itemView.context as? AppCompatActivity)?.runOnUiThread { // Refresh the previously selected item to clear its highlight notifyItemChanged(selectedPosition) // Update to the new selected position selectedPosition = clickedPosition // Refresh the newly selected item to apply highlight notifyItemChanged(selectedPosition) } } } } // ... Keep your existing interface, setOnItemClickListener, onCreateViewHolder, etc. ... // Add a method to get the currently selected position fun getSelectedPosition(): Int { return selectedPosition } }
Step 2: Use the Listener in Your Activity/Fragment
In your hosting Activity or Fragment, set up the click listener to get the selected position:
// Assume you've initialized your adapter and RecyclerView already adapter.setOnItemClickListener(object : TaskRecycleAdapter.OnItemClickListener { override fun onItemClick(position: Int) { // This gives you the position of the clicked/selected item Log.d("SelectedItem", "Current selected position: $position") // You can also get the corresponding task data val selectedTask = adapter.getTaskAt(position) // Handle the selected task as needed } })
To track which CheckBoxes are selected, we'll add a set to store checked positions, bind the CheckBox state correctly (to avoid RecyclerView's view reuse issues), and expose the checked positions externally.
Step 1: Update the Adapter to Track Checked Positions
Modify TaskRecyclerAdapter.kt to add tracking for CheckBox selections:
class TaskRecycleAdapter: RecyclerView.Adapter<TaskRecycleAdapter.MyViewHolder>() { private var list = emptyList<Data>() private lateinit var mListener : OnItemClickListener private var selectedPosition = -1 // Store all positions where the CheckBox is checked private val checkedPositions = mutableSetOf<Int>() // Optional: Listener to notify external code of CheckBox state changes private var mCheckedListener: OnCheckedChangeListener? = null class MyViewHolder(binding: TaskHolderBinding, listener: OnItemClickListener, private val adapter: TaskRecycleAdapter): RecyclerView.ViewHolder(binding.root) { private val checkBox = binding.checkBox init { itemView.setOnClickListener { val clickedPosition = adapterPosition listener.onItemClick(clickedPosition) (itemView.context as? AppCompatActivity)?.runOnUiThread { adapter.notifyItemChanged(adapter.selectedPosition) adapter.selectedPosition = clickedPosition adapter.notifyItemChanged(adapter.selectedPosition) } } // Handle CheckBox state changes checkBox.setOnCheckedChangeListener { _, isChecked -> val position = adapterPosition if (isChecked) { adapter.checkedPositions.add(position) } else { adapter.checkedPositions.remove(position) } // Notify external code if needed adapter.mCheckedListener?.onCheckedChanged(position, isChecked) } } // Bind the CheckBox state to avoid reuse issues fun bind(isChecked: Boolean) { checkBox.isChecked = isChecked } } // Optional interface for external CheckBox state updates interface OnCheckedChangeListener { fun onCheckedChanged(position: Int, isChecked: Boolean) } fun setOnCheckedChangeListener(listener: OnCheckedChangeListener) { mCheckedListener = listener } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder { val binding = TaskHolderBinding.inflate(LayoutInflater.from(parent.context), parent, false) return MyViewHolder(binding, mListener, this) } override fun onBindViewHolder(holder: MyViewHolder, position: Int) { val item = list[position] holder.itemView.findViewById<TextView>(R.id.task).text = item.task holder.itemView.findViewById<TextView>(R.id.taskDescription).text = item.task_Details // Bind the correct CheckBox state for this position holder.bind(checkedPositions.contains(position)) } // ... Keep your existing getItemCount, setData, getTaskAt methods ... // Get all checked positions (returns an immutable set to prevent external modification) fun getCheckedPositions(): Set<Int> { return checkedPositions.toSet() } }
Step 2: Use the CheckBox Listener (Optional) and Get Checked Positions
In your Activity/Fragment, you can listen for CheckBox changes or retrieve all checked positions at any time:
// Listen for CheckBox state changes (optional) adapter.setOnCheckedChangeListener(object : TaskRecycleAdapter.OnCheckedChangeListener { override fun onCheckedChanged(position: Int, isChecked: Boolean) { Log.d("CheckBoxStatus", "Position $position was ${if (isChecked) "checked" else "unchecked"}") } }) // When you need to get all checked positions (e.g., on a button click) val allCheckedPositions = adapter.getCheckedPositions() Log.d("AllChecked", "All checked positions: $allCheckedPositions") // You can loop through these positions to get the corresponding tasks allCheckedPositions.forEach { position -> val checkedTask = adapter.getTaskAt(position) // Process the checked task }
内容的提问来源于stack exchange,提问作者Dominik

