2

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.

'n' and 'o' are not chekced

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, ...)
}
Tobi
  • 100
  • 9

1 Answers1

1

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.

Tobi
  • 100
  • 9
  • I wouldn't recommend this approach, you can do this in the `bind` as part of the adapter, basically like we do it here: https://github.com/ExpensiveBelly/RecyclerViewSelection/blob/master/app/src/main/java/com/example/recyclerviewselection/ItemsAdapter.kt – ExpensiveBelly May 16 '21 at 19:05
  • Thanks for your comment! I added a part of my 'bind' method to the question. Of course I togle the view status according to the selection mode in the 'bind' method. To solve the problem described, I also have to override the 'onViewAttachedToWindow' method. – Tobi May 24 '21 at 09:38
  • This essentially causes each view to be rebound when it becomes visible. May cause performance problems if the user is scrolling quickly. It does solve the problem though. @Tobi it isn't clear how your link solves the problem. It'd help if you could write an answer and explain what part addresses this. – Jeffrey Blattman Mar 11 '22 at 20:59