ImageView 在 RecyclerView 中滚动后丢失了它们的位置

ImageView lost their position after scrolling in RecyclerView

每次在 RecyclerView 中滚动后,图像的位置都会受到干扰。我正在使用 Picasso 库将图像放入 RecyclerViewAdapter 中。我已经测试了 recyclerView 它工作正常,问题出在 onBindViewHolder .

在此 VIDEO 中,您可以看到第一个“你好”消息消失了,另一张图片占据了那个位置。

override fun onBindViewHolder(holder: ViewHolder, position: Int) {
  val chat: Chat = mChatList[position]

  //image message
    if(chat.getMessage() == "IMAGE" && chat.getUrl() != ""){

        if(chat.getSender() == currentUserID){
            holder.textMessage?.visibility = GONE
            holder.imageMessageOut?.visibility = VISIBLE
            holder.cardViewOut?.visibility = VISIBLE
            Picasso.get().load(chat.getUrl()).into(holder.imageMessageOut)
        }
        else if (chat.getSender() != currentUserID){
            holder.textMessage?.visibility = GONE
            holder.imageMessageIn?.visibility = VISIBLE
            holder.cardViewIn?.visibility = VISIBLE
            Picasso.get().load(chat.getUrl()).into(holder.imageMessageIn)
        }
    }

 //text message
    else {
        holder.textMessage?.text = chat.getMessage()
    }
}

此代码用于外发消息的布局。这是发件人的一面。

        <androidx.cardview.widget.CardView
            android:id="@+id/card_out"
            android:layout_width="190dp"
            android:layout_height="190dp"
            android:visibility="gone"
            app:cardCornerRadius="10dp"
            app:cardElevation="0dp"
            app:cardBackgroundColor="#8DE3E3E3">

        <ImageView
            android:id="@+id/outgoing_image_message_iv"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:visibility="gone" />

        </androidx.cardview.widget.CardView>

        <TextView
            android:id="@+id/text_message_tv"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@drawable/shape_rounded_rectangle"/>

并且此错误消息不断出现在 logcat。

E/UIFirst: failed to open /proc/31416/stuck_info, No such file or directory

首先:你之前的问题被关闭了,因为“这个问题需要调试细节”。所以你已经将代码交换为图像,post编辑了完全相同的内容,仍然没有调试数据...为什么你认为这个问题也不值得关闭?

您的问题出在 Picasso 图片加载中 - 您正在启动它,但当您的 ViewHolder 在加载图片之前被回收时,您永远不会取消。阅读回收模式的工作原理(re-using 之前膨胀 View/layout/row)并实施取消 Picasso 请求,如 HERE

如果您在 XML 中切换顺序 - CardView 首先显示图像,然后再显示图像 TextView - 那么您将在顶部获得“hello”文本并在其下方显示已加载的图像.因为这个 View 之前被膨胀为图像,Picasso 开始加载图像(network/cache,这需要一些时间)并且 post 它到 ImageView (使用自动 visibility change),在设置图像的那一刻属于另一个位置的另一个消息 - View 在另一个位置回收和重复使用

出现此问题是因为您没有取消 Picasso 的请求,所以每当您滚动 RecyclerView 时,图像就会开始加载,它们会被图像请求弄糊涂并开始出现在ImageView 所以你只需要像这样取消条件的 else 块中的请求

Picasso.get().cancelRequest(imageMessageOut)

现在您会看到 ImageView 是空的,但是因为您将 ImageViewCardView 的可见性设置为在 [=31= 的条件下可见]image message 所以你会在消息的地方看到一个空白 CardView。因此,为此您必须隐藏 ImageViewCardView 或仅隐藏 CardView,因为它是 ImageView 的父布局,所以只需在其他地方将它们的可见性设置为 GONE像这样的图像消息块

cardViewOut?.visibility = GONE

并且不要忘记将 textMessage 的可见性设置为 VISIBLE,因为它在 if 块中已设置为 GONE

textMessage?.visibility = VISIBLE