我正在嘗試在 RecyclerView 串列上添加一些搜索而不使用
notifyDataSetChanged()
而不是使用它
diffutil.callback()
但問題是它正確更改了串列,但沒有正確更改 UI
這是我的代碼,我會解釋它
class RecordsAdapter : RecyclerView.Adapter<RecordsAdapter.ViewHolder>() {
var adapterList = listOf<CustomerModel>()
var modelList = listOf<CustomerModel>()
set(value) {
adapterList = value
field = value
}
private var modelListFiltered = listOf<CustomerModel>()
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder =
ViewHolder(CustomerCellBinding.inflate(LayoutInflater.from(parent.context), parent, false))
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.bind(adapterList[position])
}
override fun getItemCount(): Int = adapterList.size
fun filter(isFiltered: Boolean, filterSearch: String) {
if (isFiltered) {
val filter = modelList
.filter {
it.name.contains(filterSearch) || it.id.contains(filterSearch)
}
modelListFiltered = filter
}
adapterList = if (isFiltered) modelListFiltered else modelList
val diff = CartDiffUtil(
if (isFiltered) modelList else modelListFiltered,
if (isFiltered) modelListFiltered else modelList
)
DiffUtil.calculateDiff(diff).dispatchUpdatesTo(this)
}
inner class ViewHolder(private var binding: CustomerCellBinding) :
RecyclerView.ViewHolder(binding.root) {
fun bind(model: CustomerModel) {
binding.let {
it.model = model
it.executePendingBindings()
}
}
}
}
class CartDiffUtil(private val oldList: List<CustomerModel>, private val newList: List<CustomerModel>) : DiffUtil.Callback() {
override fun getOldListSize() = oldList.size
override fun getNewListSize() = newList.size
override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean =
oldList[oldItemPosition].id == newList[newItemPosition].id
override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean =
oldList[oldItemPosition] == newList[newItemPosition]
}
所以我呼叫過濾器函式進行過濾,如果有任何過濾器,我會發送兩個引數,第二個是搜索。
現在問題出現在這種情況下
0.搜索“”
1.搜索“測驗2”
2.搜索“測驗4”
3.搜索“測驗2”
4.搜索“”


正如您在圖片中看到的,當我在“測驗 4”之后搜索“測驗 2”時,它一直顯示“測驗 4”,即使我清除搜索,它也會給我兩個“測驗 4”單元格而不是一個“測驗” 2”和一個“測驗4”
希望我的問題很清楚。
謝謝。
uj5u.com熱心網友回復:
我猜您對三個串列屬性的處理會導致某些情況下,在 DiffUtil 的前后可能存在相同的串列實體,因此無法成功比較它們。
此外,當您想使用 DiffUtil 時,使用 ListAdapter 而不是 RecyclerView.Adapter 要容易得多。請注意,當您使用 ListAdapter 時,您使用 ItemCallback 而不是 Callback。ItemCallback 更簡單。
嘗試這樣做,只有modelList當它或過濾器更改時,您確定新串列是什么并將其提交給 ListAdapter 并讓它處理更改。
class RecordsAdapter : ListAdapter<CustomerModel, RecordsAdapter.ViewHolder>(CustomerModelCallback) {
var modelList = listOf<CustomerModel>()
set(value) {
field = value
resync()
}
private var filterText: String = ""
private var isFiltered: Boolean = false
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder =
ViewHolder(CustomerCellBinding.inflate(LayoutInflater.from(parent.context), parent, false))
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.bind(adapterList[position])
}
fun filter(isFiltered: Boolean, filterText: String = "") {
this.isFiltered = isFiltered
this.filterText = filterText
resync()
}
private fun resync() {
val newList = when {
isFiltered && filterText.isNotEmpty() ->
modelList.filter {
it.name.contains(filterSearch) || it.id.contains(filterSearch)
}
else -> modelList
}
submitList(newList)
}
// view holder...
}
object CustomerModelCallback : DiffUtil.ItemCallback<CustomerModel>() {
override fun areItemsTheSame(oldItem: CustomerModel, newItem: CustomerModel): Boolean =
oldItem.id == newItem.id
override fun areContentsTheSame(oldItem: CustomerModel, newItem: CustomerModel): Boolean =
oldItem == newItem
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/442555.html
標籤:安卓 安卓工作室 科特林 android-recyclerview android-diffutils
下一篇::app:compileDebugAndroidTestKotlingFAILED未解決的參考:className多模塊專案
