首页 > 解决方案 > 如何通过将键设置为字符串来使用recyclerview-selection?

问题描述

使用 android 库androidx.recyclerview.selection,我尝试按照此处此处RecyclerView的教程实现多项选择。

但是,我希望我key成为一个String,而不是Long,但我面临两个错误,如下所示:

tracker = SelectionTracker.Builder<String>(
    "selection_id",
    recyclerView,
    StableIdKeyProvider(recyclerView),    // this line shows error
    MyItemDetailsLookup(recyclerView),
    StorageStrategy.createStringStorage()    // this line shows error
    ).withSelectionPredicate(
        SelectionPredicates.createSelectAnything()
    ).build()

我想要一些关于如何ItemKeyProvider为 a 实现的细节String,其次,

StorageStrategy.createStringStorage() // this shows error
StorageStrategy.createLongStorage()   // this doesn't show error

为什么会发生这种情况,当我到处都将泛型类型替换为Longto 时String

标签: androidkotlinandroid-recyclerview

解决方案


根据文档StorageStrategy用于存储已保存状态的密钥,

/* for    Long    keys */    StorageStrategy.createLongStorage()
/* for   String   keys */    StorageStrategy.createStringStorage()
/* for Parcelable keys */    StorageStrategy.createParcelableStorage(Class)

此外,根据docsStableIdKeyProvider提供了 type 的键Long。这就是为什么您StorageStrategy显示错误,因为它需要Long密钥。

要提供String密钥,您必须创建自己的ItemKeyProvider类。有关 的更多详细信息ItemKeyProvider,您可以在此处参考文档

这是您可以为键实现ItemKeyProvider类的方式:String

class MyItemKeyProvider(private val rvAdapter: MyAdapter): ItemKeyProvider<String>(SCOPE_CACHED) {
    override fun getKey(position: Int): String = rvAdapter.getItem(position).myKey
    override fun getPosition(key: String): Int = rvAdapter.getPosition(key)
}

并在MyAdapter

class MyAdapter(private val myList: ArrayList<MyModel>): RecyclerView.Adapter<MyAdapter.MyViewHolder>() {
    // functions used in MyItemKeyProvider
    fun getItem(position: Int) = myList[position]
    fun getPosition(key: String) = myList.indexOfFirst { it.myKey == key }

    // other functions
}

MyModel像这样的东西在哪里:

data class MyModel (
    val myKey: String,
    // other data
)

现在,您可以SelectionTracker像这样简单地构建您的:

myTracker = SelectionTracker.Builder(
        "my_selection_id",
        recyclerView,
        MyItemKeyProvider(rvAdapter),
        MyItemDetailsLookup(recyclerView),
        StorageStrategy.createStringStorage()
    ).withSelectionPredicate(
        SelectionPredicates.createSelectAnything()
    ).build()

请注意,Adapter如果您不使用,则不应在您的代码中编写以下代码StableIdKeyProvider

init { setHasStableIds(true) }

否则它将显示此错误:

Attempt to invoke virtual method 'boolean androidx.recyclerview.widget.RecyclerView$ViewHolder.shouldIgnore()' on a null object reference

教程展示了如何recyclerview-selection使用Long键实现,还展示了如何实现您自己ItemKeyProvider的键类Long

recyclerview-selection使用Parcelable键实现,我在这里找到了示例代码。


推荐阅读