Android 如何通过将键设置为字符串来使用recyclerview选择?

Android 如何通过将键设置为字符串来使用recyclerview选择?,android,kotlin,android-recyclerview,Android,Kotlin,Android Recyclerview,通过使用android库androidx.recyclerview.selection,我尝试在教程和之后的recyclerview中实现多个选择 但是,我希望我的键是字符串,而不是长,但我面临以下两个错误: tracker = SelectionTracker.Builder<String>( "selection_id", recyclerView, StableIdKeyProvider(recyclerView), // this line sh

通过使用android库androidx.recyclerview.selection,我尝试在教程和之后的
recyclerview
中实现多个选择

但是,我希望我的
字符串
,而不是
,但我面临以下两个错误:

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()
为什么会发生这种情况,当我将通用类型从
Long
替换为
String

根据存储策略,
StorageStrategy
用于存储处于保存状态的密钥

/* for    Long    keys */    StorageStrategy.createLongStorage()
/* for   String   keys */    StorageStrategy.createStringStorage()
/* for Parcelable keys */    StorageStrategy.createParcelableStorage(Class)
此外,根据,
StableIdKeyProvider
提供了
Long
类型的密钥。这就是为什么
StorageStrategy
显示错误,因为它需要
Long

要提供
String
键,您必须创建自己的
ItemKeyProvider
类。有关
ItemKeyProvider
的更多详细信息,请参阅此处

这就是如何为
String
键实现
ItemKeyProvider
类的方法:

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)
}
其中
MyModel
是这样的:

data class MyModel (
    val myKey: String,
    // other data
)
myTracker = SelectionTracker.Builder(
        "my_selection_id",
        recyclerView,
        MyItemKeyProvider(rvAdapter),
        MyItemDetailsLookup(recyclerView),
        StorageStrategy.createStringStorage()
    ).withSelectionPredicate(
        SelectionPredicates.createSelectAnything()
    ).build()
现在,您可以像这样简单地构建
SelectionTracker

data class MyModel (
    val myKey: String,
    // other data
)
myTracker = SelectionTracker.Builder(
        "my_selection_id",
        recyclerView,
        MyItemKeyProvider(rvAdapter),
        MyItemDetailsLookup(recyclerView),
        StorageStrategy.createStringStorage()
    ).withSelectionPredicate(
        SelectionPredicates.createSelectAnything()
    ).build()
请注意,如果未使用
StableIdKeyProvider
,则不应在
适配器中编写以下代码:

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
}
init { setHasStableIds(true) }
否则将显示此错误:

Attempt to invoke virtual method 'boolean androidx.recyclerview.widget.RecyclerView$ViewHolder.shouldIgnore()' on a null object reference
这显示了如何使用
Long
键实现
recyclerview选择
,还显示了如何为
Long
键实现自己的
ItemKeyProvider

要使用
Parcelable
键实现
recyclerview选择
,我找到了一个示例代码