Has*_*isi 1 android android-studio android-recyclerview android-diffutils
如果适配器接收单个数据类型对象,我知道如何实现 DiffUtil。
但就我而言,我有一个适配器,它从片段中获取两种数据类型。
那么如何将 DiffUtil 与多种数据类型一起使用呢?
这是我的适配器代码:
class VisitorsAdapter(val listener: VisitorsViewHolder.OnVisitorClicked) :
RecyclerView.Adapter<BaseViewHolder<*>>() {
private var visitorsData = mutableListOf<Any>()
private var isOwner = true
fun setData(visitorsData: List<Any>) {
Log.e("TAG", "setData called")
this.visitorsData.clear()
var currentVisitors = mutableListOf<CurrentVisitorResponseItem>()
var leavedVisitors = mutableListOf<LeavedVisitorsResponseItem>()
for (visitor in visitorsData) {
when (visitor) {
is CurrentVisitorResponseItem -> currentVisitors.add(visitor)
is LeavedVisitorsResponseItem -> leavedVisitors.add(visitor)
}
}
currentVisitors = currentVisitors.sortedBy { it.roomNumber?.toInt() }.toMutableList()
leavedVisitors = leavedVisitors.sortedBy { it.room }.toMutableList()
this.visitorsData.addAll(currentVisitors)
this.visitorsData.addAll(leavedVisitors)
notifyDataSetChanged()
}
fun isOwner(chooser: Boolean) {
this.isOwner = chooser
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BaseViewHolder<*> {
return VisitorsViewHolder(
LayoutInflater.from(parent.context).inflate(R.layout.visitor_item, parent, false)
)
}
override fun getItemCount() = visitorsData.size
override fun onBindViewHolder(holder: BaseViewHolder<*>, position: Int) {
val dataPositioned = visitorsData[position]
when (holder) {
is VisitorsViewHolder -> {
holder.bind(dataPositioned, position, listener, isOwner)
}
}
}
Run Code Online (Sandbox Code Playgroud)
}
注意:我有两种类型的数据:
1- 当前访客响应项
2-离开的访客响应项目
我找到了解决方案!
首先,如果我们尝试将ItemCallback的类型设为(Any),我们将面临一个问题
说“可疑的相等性检查:Object DiffUtilEquals 中未实现 equals()”
解决方案是创建一个重写 equals 函数的接口
并在我们想要传递的数据类上实现该接口。像这样:
interface Equatable {
override fun equals(other: Any?): Boolean
}
data class CurrentVisitorResponseItem() : Equatable
data class LeavedVisitorsResponseItem() : Equatable
Run Code Online (Sandbox Code Playgroud)
那么,适配器类将是这样的:
class VisitorsAdapter(val listener: VisitorsViewHolder.OnVisitorClicked) :
RecyclerView.Adapter<BaseViewHolder<*>>() {
private var isOwner = true
private val differCallBack = object : DiffUtil.ItemCallback<Equatable>() {
override fun areItemsTheSame(oldItem: Equatable, newItem: Equatable): Boolean {
Log.e("TAG", "I'm in the areItemsTheSame")
return when {
oldItem is CurrentVisitorResponseItem && newItem is CurrentVisitorResponseItem -> {
oldItem.id == newItem.id
}
oldItem is LeavedVisitorsResponseItem && newItem is LeavedVisitorsResponseItem -> {
oldItem.id == newItem.id
}
else -> false
}
}
override fun areContentsTheSame(oldItem: Equatable, newItem: Equatable): Boolean {
return when {
oldItem is CurrentVisitorResponseItem && newItem is CurrentVisitorResponseItem -> {
oldItem == newItem
}
oldItem is LeavedVisitorsResponseItem && newItem is LeavedVisitorsResponseItem -> {
oldItem == newItem
}
else -> false
}
}
}
val differ = AsyncListDiffer(this, differCallBack)
fun isOwner(chooser: Boolean) {
this.isOwner = chooser
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BaseViewHolder<*> {
return VisitorsViewHolder(
LayoutInflater.from(parent.context).inflate(R.layout.visitor_item, parent, false)
)
}
override fun getItemCount() = differ.currentList.size
override fun onBindViewHolder(holder: BaseViewHolder<*>, position: Int) {
val dataPositioned = differ.currentList[position]
when (holder) {
is VisitorsViewHolder -> {
holder.bind(dataPositioned, position, listener, isOwner)
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3159 次 |
| 最近记录: |