RecyclerView ViewHolder 在不应该更改视图时更改视图

Posted

技术标签:

【中文标题】RecyclerView ViewHolder 在不应该更改视图时更改视图【英文标题】:RecyclerView ViewHolder changing views when it shouldn't be 【发布时间】:2021-10-28 07:38:21 【问题描述】:

对于我的 recyclerview 中的每 21 个项目,我想让该视图中的图像更大。 应该足够简单

我将此代码添加到我的 ItemAdapter 类的 onBindViewHolder:

    override fun onBindViewHolder(holder: ItemViewHolder, pos: Int) 
        val currentItem = getItem(pos)
        val largeItemView = pos >= 21 && pos % 21 == 0
        Log.e("ItemAdapter", "Position: $pos, largeItemView bool: $largeItemView")
        if (currentItem != null) 
            holder.bind(currentItem, pos, largeItemView)
        

largeItemView 布尔值被传递给我的 ItemViewHolder

class ItemViewHolder(private val binding: ShopProductItemBinding) :
RecyclerView.ViewHolder(binding.root) 
fun bind(item: RoomItem, pos: Int, largeItemView: Boolean) 
    var imageBefore = item.product_image_list?.substringBefore(',')
    imageBefore = addHttpsToImageUrl(imageBefore)
    if (largeItemView) 
        // This is getting called when largeItemView is false??
        binding.apply 
            imageViewItem.layoutParams.height = 800
            imageViewItem.scaleType = ImageView.ScaleType.FIT_XY
            Glide.with(itemView)
                .load(imageBefore)
                .transition(DrawableTransitionOptions.withCrossFade())
                .into(imageViewItem)
            imageViewItem.setOnClickListener 
                logProductInfo(item, pos, imageBefore, largeItemView)
            
        
     else 
        binding.apply 
            Glide.with(itemView)
                .load(imageBefore)
                .centerCrop()
                .transition(DrawableTransitionOptions.withCrossFade())
                .into(imageViewItem)
            imageViewItem.setOnClickListener 
                logProductInfo(item, pos, imageBefore, largeItemView)
            
        

    
    

recyclerview 中的每 21 个项目的高度都会增加。这是伟大的。然而,recyclerview 中的其他项目也会随机增加高度。我无法解释这一点。我已经设置了日志来显示我点击的项目的位置和布尔值。我将单击一个不应该很大的大图像项,并且日志说 largeItemView 布尔值是错误的。那么增加图片大小的代码怎么可能达到呢?

以下是一些日志输出的屏幕截图,以防万一。

这个问题让我很困惑。关于这里发生了什么的任何想法?

【问题讨论】:

Viewholders 被重用 - 您的 else 案例必须将 height 和 scaleType 恢复为默认值,以解决您绑定的 viewholder 绑定到之前触发“largeItemView”的位置的情况。 这已解决,谢谢。 像这个场景你应该使用多视图类型的 Recyclerview。它使代码更干净。 【参考方案1】:

感谢 Pawel,我有解决方案

“Viewholders 被重用 - 你的 else 情况必须将 height 和 scaleType 恢复为默认值,以解决你绑定的 viewholder 绑定到之前触发“largeItemView”的位置的情况”

我加了

 imageViewItem.layoutParams.height = 600
 imageViewItem.scaleType = ImageView.ScaleType.CENTER_CROP

到我的 itemviewholder 中的 else 块,它已经解决了这个问题。

【讨论】:

以上是关于RecyclerView ViewHolder 在不应该更改视图时更改视图的主要内容,如果未能解决你的问题,请参考以下文章

RecyclerView.ViewHolder 的 setIsRecyclable() 函数

等效于 RecyclerView 中 ViewHolder 的 onAttachedToWindow()/onDetachedFromWindow()

ViewHolder 中的嵌套 RecyclerView 破坏了折叠工具栏布局

获取特定位置的 ViewHolder - RecyclerView

在 RecyclerView 适配器中初始化 viewHolder 时出错

如何使用 StaggeredGridLayoutManager 在 RecyclerView 中确定 viewholder 是左还是右