1

如果适配器接收单一数据类型对象,我知道如何实现 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)
        }
    }
}

}

注意:我有两种类型的数据:

1- CurrentVisitorResponseItem

2- LeavedVisitorResponseItem

4

1 回答 1

4

我找到了解决方案!

首先,如果我们尝试将 ItemCallback 的类型设为 (Any) 我们将面临一个问题

说“可疑的相等检查:在 Object DiffUtilEquals 中未实现 equals()”

解决方案是创建一个覆盖等于函数的接口

并在我们要传递的数据类上实现该接口。像这样:

    interface Equatable {
    override fun equals(other: Any?): Boolean
}

data class CurrentVisitorResponseItem() : Equatable

data class LeavedVisitorsResponseItem() : Equatable

然后,适配器类将是这样的:

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)
            }
        }
    }
}
于 2020-07-22T12:22:57.510 回答