使用分页适配器第3页的嵌套recyclerview滚动后显示错误的图像

问题描述

如何解决子适配器图像变化并滚动后显示错误图像的问题?

这是我的代码

父级数据类

data class Review(
   val author: String,val date: String,val rating: Float,val comment: String,val images: List<Image>)

子数据类

对于作者和评论,我仅从父数据类中获取

data class Image(
   var author: String? = null,var comment: String? = null,val large: String,val thumbnail: String)

ParentAdapter

class ReviewAdapter(private val callback: ProductReviewImageAdapterCallback) :
PagingDataAdapter<Review,ReviewAdapter.ListViewHolder>(DIFF_CALLBACK) {

private val viewPool = RecyclerView.RecycledViewPool()

private val imageAdapter: ProductReviewImageAdapter by lazy {
    ProductReviewImageAdapter(callback)
}

companion object {
    private val DIFF_CALLBACK = object : DiffUtil.ItemCallback<Review>() {
        override fun areItemsTheSame(oldItem: Review,newItem: Review): Boolean {
            return oldItem.author == newItem.author
        }

        override fun areContentsTheSame(oldItem: Review,newItem: Review): Boolean {
            return oldItem.comment == newItem.comment
        }
    }
}


inner class ListViewHolder(itemBinding: ItemProductReviewBinding) :
    RecyclerView.ViewHolder(itemBinding.root) {
    val binding = ItemProductReviewBinding.bind(itemBinding.root)
    fun bind(data: Review,position: Int) {
      with(binding) {
            if (data.images.isEmpty()) {
                rvImageReview.gone()
            } else {
                setupImagesRecyclerView(rvImageReview)
                rvImageReview.visible()
                imageAdapter.differ.submitList(data.images)
            }

            tvNameReviewer.text = data.author
            tvReviewDesc.text = data.comment
            tvDateReview.text = data.date
            ratingBarReview.rating = data.rating

        }
    }
}


override fun onCreateViewHolder(parent: ViewGroup,viewType: Int): ListViewHolder =
    ListViewHolder(
        ItemProductReviewBinding.inflate(LayoutInflater.from(parent.context),parent,false)
    )

override fun onBindViewHolder(holder: ListViewHolder,position: Int) {
    val review = getItem(position)

    if (review != null) {
        holder.bind(review,position)
    }
}

private fun setupImagesRecyclerView(recyclerView: RecyclerView) {
    recyclerView.apply {
        layoutManager = LinearLayoutManager(context,LinearLayoutManager.HORIZONTAL,false)
        adapter = imageAdapter
        setRecycledViewPool(viewPool)
        setItemViewCacheSize(20)
    }
}

}

ChildAdapter

class ProductReviewImageAdapter(private val callback: ProductReviewImageAdapterCallback) : RecyclerView.Adapter<ProductReviewImageAdapter.ListViewHolder>() {
private val diffCallback = object : DiffUtil.ItemCallback<Image>() {
    override fun areItemsTheSame(
        oldItem: Image,newItem: Image
    ): Boolean {
        return oldItem.author == newItem.author
    }

    override fun areContentsTheSame(
        oldItem: Image,newItem: Image
    ): Boolean {
        return oldItem.comment == newItem.comment
    }

}

val differ = AsyncListDiffer(this,diffCallback)

override fun onCreateViewHolder(parent: ViewGroup,viewType: Int): ListViewHolder =
    ListViewHolder(
        ItemImageBinding.inflate(LayoutInflater.from(parent.context),false)
    )

override fun getItemCount(): Int = differ.currentList.size

override fun onBindViewHolder(holder: ListViewHolder,position: Int) {
    holder.bind(differ.currentList[position],position)
}

inner class ListViewHolder(itemBinding: ItemImageBinding) :
    RecyclerView.ViewHolder(itemBinding.root) {
    private val itemBinding = ItemImageBinding.bind(itemBinding.root)
    fun bind(data: Image,position: Int) {
        with(itemBinding) {

            image.loadImageRoundedCorner(data.thumbnail)

            image.setOnClickListener {
                callback.onProductReviewImageClicked(position,differ.currentList)
            }

        }

    }
}

}

滚动之前

第一次加载时,第一个位置数据显示适当的图像

before scrolling

稍微滚动一下

第一个位置数据中的图像更改为下一个数据中的图像

after a bit scrolling

滚动到最后一个数据/页面

最后一张图片显示不合适的图片

scroll to last data/page

*注意

  • 只有5个数据,只有第一个和最后一个数据包含图像
  • 第一个位置数据中的图像应为人物图像,最后一个位置图像应为粉红色图像
  • 我使用Coil作为图像加载器,并在加载图像之前使用了ImageView.clear()方法

在此先感谢您,我的英语不好。我不是母语人士

解决方法

更新

已修复: 事实证明,这只是在适配器初始化时出错,应该在onBindViewHolder中而不是在父适配器中初始化适配器,以便并非所有项都具有相同的适配器,从而导致所有数据更改

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...