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
是空的,但是因为您将 ImageView
和 CardView
的可见性设置为在 [=31= 的条件下可见]image message 所以你会在消息的地方看到一个空白 CardView
。因此,为此您必须隐藏 ImageView
和 CardView
或仅隐藏 CardView
,因为它是 ImageView
的父布局,所以只需在其他地方将它们的可见性设置为 GONE像这样的图像消息块
cardViewOut?.visibility = GONE
并且不要忘记将 textMessage
的可见性设置为 VISIBLE,因为它在 if 块中已设置为 GONE
textMessage?.visibility = VISIBLE
每次在 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
是空的,但是因为您将 ImageView
和 CardView
的可见性设置为在 [=31= 的条件下可见]image message 所以你会在消息的地方看到一个空白 CardView
。因此,为此您必须隐藏 ImageView
和 CardView
或仅隐藏 CardView
,因为它是 ImageView
的父布局,所以只需在其他地方将它们的可见性设置为 GONE像这样的图像消息块
cardViewOut?.visibility = GONE
并且不要忘记将 textMessage
的可见性设置为 VISIBLE,因为它在 if 块中已设置为 GONE
textMessage?.visibility = VISIBLE