I'm trying to implement the android library SelectionTracker which allows to select items in a recyclerView.
Everything works fine except that when I click outside of an item (which is in a grid layout), the all selection is cleared.
I actually have found the code which calls the clearSelection()
. It's on the line 78 of the class TouchInputHandler.
It then calls the line 64 of ItemDetailsLookup which returns false
because the touch event didn't occurred on an item.
I was wondering if anyone have found a workaround to prevent this behavior, because I didn't found any option in the documentation.
It's a gridLayout so it is quite "normal" to have space between items and I don't want my users to clear the selection because they have touch the side of an item.
This is my solution, based on that if we have predefined ItemDetail that will be used as "this is not the view you can select".
First, inside your ItemDetailsLookup instead of returning null
you can pass single item with distinguish data that will make sure there is no name/position collision with any other data you can have
class AppItemDetailsLookup(private val rv: RecyclerView) : ItemDetailsLookup<String>() {
override fun getItemDetails(e: MotionEvent): ItemDetails<String>? {
val view = rv.findChildViewUnder(e.x, e.y) ?: return EMPTY_ITEM
return (rv.getChildViewHolder(view) as AppItemViewHolder).getItemDetails()
}
object EMPTY_ITEM : ItemDetails<String>() {
override fun getSelectionKey(): String? = "empty_item_selection_key_that_should_be_unique_somehow_that_is_why_i_made_it_so_long"
override fun getPosition(): Int = Integer.MAX_VALUE
}
}
And then when you are creating SelectionTracker with builder, instead of using standard predicate (default is SelectionPredicates.createSelectAnything()
) you make your own that will notify that this EMPTY_ITEM
cannot be selected
.withSelectionPredicate(object : SelectionTracker.SelectionPredicate<String>() {
override fun canSelectMultiple(): Boolean = true
override fun canSetStateForKey(key: String, nextState: Boolean): Boolean =
key != AppItemDetailsLookup.EMPTY_ITEM.selectionKey
override fun canSetStateAtPosition(position: Int, nextState: Boolean): Boolean =
position != AppItemDetailsLookup.EMPTY_ITEM.position
})
I tested it with LinearLayoutManger, the selection was deselecting all items once i clicked outside any of them (my items did not had spacing decoration, but there were so few of them that i was seeing empty under last item)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With