如何通过将键设置为字符串来使用 recyclerview-selection?

Aks*_*ngh 3 android kotlin android-recyclerview

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

但是,我希望我keyString, 而不是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()
Run Code Online (Sandbox Code Playgroud)

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

StorageStrategy.createStringStorage() // this shows error
StorageStrategy.createLongStorage()   // this doesn't show error
Run Code Online (Sandbox Code Playgroud)

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

Aks*_*ngh 9

根据文档StorageStrategy用于在保存状态下存储密钥,

/* for    Long    keys */    StorageStrategy.createLongStorage()
/* for   String   keys */    StorageStrategy.createStringStorage()
/* for Parcelable keys */    StorageStrategy.createParcelableStorage(Class)
Run Code Online (Sandbox Code Playgroud)

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

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

这是您可以ItemKeyProviderString键实现类的方法:

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

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

哪里MyModel是这样的:

data class MyModel (
    val myKey: String,
    // other data
)
Run Code Online (Sandbox Code Playgroud)

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

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

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

init { setHasStableIds(true) }
Run Code Online (Sandbox Code Playgroud)

否则会显示这个错误:

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

教程展示了如何recyclerview-selection使用Long密钥实现,还展示了如何实现自己ItemKeyProviderLong密钥类。

为了recyclerview-selection使用Parcelable密钥实现,我在这里找到了一个示例代码。