RecyclerView过滤数据后显示错误,过滤结果Log正常如何排查修复?
问题根因
- 你的适配器将
CardItemForListBinding定义为全局属性,每次执行onCreateViewHolder创建新条目时都会覆盖这个binding的引用,最终所有条目绑定时都会修改最后一个创建的条目的视图,导致展示错乱。 onBindViewHolder中每次绑定都对列表做实时排序,排序返回新列表会导致位置和数据对应错位。
修复方案
1. 修正适配器代码
class CardDetailsFilterableAdapter: RecyclerView.Adapter<CardDetailsFilterableAdapter.CardDetailsViewHolder>(){ var cardsListFiltered: ArrayList<BanksCardModel> = ArrayList() lateinit var mContext:Context var onItemClick: ((BanksCardModel) -> Unit)? = null inner class CardDetailsViewHolder(val binding: CardItemForListBinding) : RecyclerView.ViewHolder(binding.root) override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CardDetailsViewHolder { mContext = parent.context // 每个ViewHolder单独持有自己的binding实例,不要用全局变量 val binding = CardItemForListBinding.inflate(LayoutInflater.from(parent.context), parent, false) return CardDetailsViewHolder(binding) } override fun onBindViewHolder(holder: CardDetailsViewHolder, position: Int) { val currentItem = cardsListFiltered[position] bind(holder.binding, currentItem) } private fun bind(binding: CardItemForListBinding, item: BanksCardModel) { Log.d("onbindViewHolder", item.username) binding.cardItemCardHolder.setText(item.username) binding.bankName.setText(item.bankName) setCardOrShebaNumberToViews(item.cardNumber, cardParts) setCardOrShebaNumberToViews(item.shabaNumber, shebaParts) binding.cardExpireDateMonth.setText(item.expireMonth) binding.cardExpireDateYear.setText(item.expireYear) binding.cardCvv2Number.setText(item.cvv2Number) } override fun getItemCount(): Int = cardsListFiltered.size fun addData(list: List<BanksCardModel>) { cardsListFiltered.clear() // 统一在更新数据时排序,避免每次绑定重复排序导致位置错位 cardsListFiltered.addAll(list.sortedBy { it.id }) notifyDataSetChanged() } }
2. 可选优化Fragment搜索逻辑(避免空指针)
override fun onQueryTextChange(newText: String?): Boolean { val searchContent = newText.orEmpty() val temp = ArrayList<BanksCardModel>() for (part in fullListCards){ // 如需不区分大小写搜索,可改为 part.username.lowercase().contains(searchContent.lowercase()) if (part.username.contains(searchContent)){ temp.add(part) } } filterableAdapter.addData(temp) return false }
内容的提问来源于stack exchange,提问作者moslem
相关产品推荐
相关产品推荐

