首页 > 解决方案 > ImageView 在 RecyclerView 中滚动后失去了位置

问题描述

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

在此视频 中,您可以看到第一个“你好”消息消失了,而另一个图像取代了该位置。

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

标签: androidfirebaseadapterpicasso

解决方案


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

您的问题在于Picasso图像加载-您正在启动它,但是ViewHolder在加载图像之前被回收时永远不会取消。阅读回收模式的工作原理(重新使用以前膨胀的View/layout/row)并实现取消Picasso请求,如HERE

如果您在 XML 中切换顺序 -CardView首先是图像,其次是图像TextView- 那么您将在顶部获得“hello”文本并在其下获得加载的图像。因为这View以前被膨胀为图像,Picasso开始加载图像(网络/缓存,这需要一些时间)并将其发布到ImageView(自动visibility更改),在设置图像的那一刻属于另一个位置的另一条消息 - 在另一个位置View回收和重用位置


推荐阅读