Android RecyclerView SelectionTracker 在外部触摸时清除选择

Ben*_*det 6 android android-recyclerview

我正在尝试实现允许在 recyclerView 中选择项目的 android 库SelectionTracker

一切正常,除了当我在项目外部(在网格布局中)单击时 ,所有选择都被清除。

我实际上已经找到了调用clearSelection(). 它位于类TouchInputHandler的第 78 行。然后它调用ItemDetailsLookup的第 64 行,该行返回,false因为触摸事件没有发生在项目上。

我想知道是否有人找到了防止这种行为的解决方法,因为我没有在文档中找到任何选项。

这是一个 gridLayout,因此在项目之间留有空间是非常“正常的”,我不希望我的用户清除选择,因为他们触摸了项目的侧面。

V-m*_*ter 6

这是我的解决方案,基于如果我们有预定义的 ItemDetail 将用作“这不是您可以选择的视图”。

首先,在您的 ItemDetailsLookup 中而不是返回null您可以传递具有区分数据的单个项目,以确保没有名称/位置与您可以拥有的任何其他数据发生冲突

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
    }

}
Run Code Online (Sandbox Code Playgroud)

然后,当您使用构建器创建 SelectionTracker 时,您不使用标准谓词(默认为SelectionPredicates.createSelectAnything()),而是创建自己的谓词,以通知EMPTY_ITEM无法选择该谓词

.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
})
Run Code Online (Sandbox Code Playgroud)

我用 LinearLayoutManger 对其进行了测试,一旦我在其中任何一个项目之外单击,选择就会取消选择所有项目(我的项目没有间距装饰,但是它们太少了,我在最后一个项目下看到空的)