Android RecyclerView SelectionTracker清除触摸外部的选择

时间:2019-11-15 15:48:18

标签: android android-recyclerview

我正在尝试实现Android库SelectionTracker,该库允许在recyclerView中选择项目。

一切正常,除了当我单击 item (which is in a grid layout),将清除所有选择。

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

我想知道是否有人找到解决此问题的方法,因为我在文档中没有找到任何选择。

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

1 个答案:

答案 0 :(得分:4)

这是我的解决方案,基于此,如果我们有预定义的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
    }

}

然后,当您使用构建器创建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
})

我使用LinearLayoutManger对其进行了测试,一旦我在其中的任何一个项目上单击鼠标,便取消了对所有项目的选择(我的项目没有间隔装饰,但是其中的项目太少了,以至于我在上一个项目下看到的都是空白)