Reputation: 100
I have implemented the recyclerview-selection library successfully. Now I am trying to make a "select all items" button with the method SelectionTracker.setItemsSelected(keys: Iterable<K>, selected: boolean)
. So far so good. My problem is now that some of the items which are out of sight don´t get visually checked. But this just happens if I scrolled down to the list´s end bevor pressing the button. Under the hood all items get checked which I can see on the app bar´s text.
Example: I scroll to the end of the list and back up and press then the "select all items" button. As you can see in the picture there a some items that are visually not checked.
Similar things happen if I press the back button to remove the checked state of all items.
Now my question: Is there a bug in the recyclerview libraries which causes this weird gui behaviour or am I doing something wrong? I am using the following version: recyclerview-selection:1.1.0-rc03
EDIT:
Here the bind method of my RecyclerView.ViewHolder class:
fun bind(event: Event, selected: Boolean) {
val imgSize = if (selected) SELECTION_IMG_EXTENDED_SIZE else SELECTION_IMG_REDUCED_SIZE
animateResize(imgSize, ...)
}
Upvotes: 2
Views: 392
Reputation: 100
According to the documentation I solved the problem by overriding the following method:
RecyclerView.Adapter:
override fun onViewAttachedToWindow(holder: RecyclerView.ViewHolder) {
val isSelected = selectionTracker.isSelected(holder.itemId)
holder.setItemSelected(isSelected)
}
I don't know if this is the recommended way to solve the problem but maybe it will help someone. Let me know if you have any more tips or information for me!
EDIT:
Here the full code:
class EventAdapterAll(private val context: Context) : ListAdapter<Event, EventAdapterAll.EventViewHolder>(EventAdapterDiffCallback()) {
private val commonListAdapter = CommonListAdapter()
init {
setHasStableIds(true)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): EventViewHolder {
val binding = LayoutEventItemAllBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return EventViewHolder(binding)
}
override fun onBindViewHolder(holder: EventViewHolder, position: Int) {
val currentItem = getItem(position)
commonListAdapter.selectionTracker?.let {
holder.bind(currentItem, it.isSelected(getItemId(position)))
}
}
override fun onViewAttachedToWindow(holder: EventViewHolder) {
val isSelected = commonListAdapter.selectionTracker?.isSelected(holder.itemId)
if (isSelected != null) {
holder.setItemSelected(isSelected)
}
}
//...
inner class EventViewHolder(private val binding: LayoutEventItemAllBinding) : RecyclerView.ViewHolder(binding.root) {
fun bind(event: Event, selected: Boolean) = with(binding) {
setItemSelected(selected)
//...
}
fun setItemSelected(selected: Boolean) {
val imgSize = if (selected) SELECTION_IMG_EXTENDED_SIZE else SELECTION_IMG_REDUCED_SIZE
commonListAdapter.animateResize(binding.imgEventSelection, imgSize, context)
}
}
}
When scrolling down/up and the list items become visible, onViewAttachedToWindow
ensures that the selection status in the list gets updated.
Upvotes: 1