多视图类型回收器查看图像滚动查看大小更改



我有一个具有多个视图类型的recyclerview。其中一个在布局中具有imageview

<ImageView
android:id="@+id/img_rcv_msg_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:scaleType="fitXY"
app:imgBottomRightCorner="10dp"
app:imgTopLeftCorner="10dp"
app:srcCompat="@android:drawable/ic_menu_report_image"
tools:ignore="ContentDescription" />

在BindViewHolder内部,我使用Glide将图像加载到视图

// I have added this
rcvImageView.apply {
layout(0,0,0,0)
}
Glide.with(activityContext).load(previewFile).into(rcvImageView)

我已经对代码进行了编程,因此图像文件的尺寸有效,适合屏幕。然而,当我滚动recyclerView时,相同的图像显示为不同的大小。。。!!为什么会发生这种情况?

编辑时间:在使用Glide设置图像之前,我添加了布局(0,0,0,0(,但现在的问题是,创建视图时图像的尺寸为0,Glide加载图像后的图像的尺寸相应。那一刻,上面所有的项目都被向上推,因为一个已经创建的项目改变了它的高度!

之所以会发生这种情况,是因为ViewHolders重用对象,并且当您滚动时,它将显示一些以前加载的图像。你可以通过使用.diskCacheStrategy(DiskCacheStrategy.NONE)和Glide来停止这种情况,如下所示:

Glide.with(activityContext)
.load(yourFileDataModel)
.diskCacheStrategy(DiskCacheStrategy.NONE)
.into(yourImageView);

或者你可以使用这样的签名:

Glide.with(activityContext)
.load(yourFileDataModel)
.signature(new StringSignature(String.valueOf(System.currentTimeMillis())))
.into(yourImageView);

每次在适配器的onBindViewHolder方法中回收视图时,尝试将ViewHolder中的图像重置为原始大小。

因此,当视图被回收(滚动时(时,ImageView可以重置为原始大小。

onBindViewHolder(...)
holder.imageView.layout(0, 0, 0, 0);

来源:中@TWiStErRob的评论

经过大量研究,我最终制作了一个自定义解决方案,因为您不可能拥有一个将wrap_content设置为Width AND Height的ImageView,并期望回收视图在滚动后不更改大小。我所做的是拥有ImageViews,一个用于Portrait,另一个用于LandScape和Cube

<ImageView
android:id="@+id/img_snt_msg_image_landscape"
android:layout_width="320dp"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:scaleType="fitXY"
android:maxWidth="320dp"
android:maxHeight="320dp"
android:minWidth="150dp"
android:minHeight="150dp"
android:src="@drawable/error_image"
app:imgBottomRightCorner="10dp"
app:imgTopLeftCorner="10dp"
tools:ignore="ContentDescription" />
<ImageView
android:id="@+id/img_snt_msg_image_portrait"
android:layout_width="wrap_content"
android:layout_height="320dp"
android:adjustViewBounds="true"
android:scaleType="fitXY"
android:maxWidth="320dp"
android:maxHeight="320dp"
android:minWidth="150dp"
android:minHeight="150dp"
android:src="@drawable/error_image"
app:imgBottomRightCorner="10dp"
app:imgTopLeftCorner="10dp"
tools:ignore="ContentDescription" />

正如你所看到的,每个维度都有一个最小值和最大值。但是在它们的宽度和高度之间切换wrap_content。因此,风景图像具有固定的宽度,肖像图像具有固定高度。在onbind查看器内,根据方向,我隐藏了正确的图像View并显示另一个!

sntImageViewLand.setImageDrawable(ContextCompat.getDrawable(itemView.context, R.drawable.loading_image))
sntImageViewLand.visibility = View.VISIBLE
sntImageViewPortrait.visibility = View.GONE
when (it.orientation) {
LANDSCAPE, CUBE -> {
Glide
.with(activityContext)
.load(previewFile)
.diskCacheStrategy(DiskCacheStrategy.NONE)
.into(sntImageViewLand)
sntImageViewLand.setOnClickListener {
itemCallback.onRowClicked(adapterPosition, messageItem)
}
sntImageViewLand.visibility = View.VISIBLE
sntImageViewPortrait.visibility = View.GONE
}
PORTRAIT -> {
Glide
.with(activityContext)
.load(previewFile)
.diskCacheStrategy(DiskCacheStrategy.NONE)
.into(sntImageViewPortrait)
sntImageViewPortrait.setOnClickListener {
itemCallback.onRowClicked(adapterPosition, messageItem)
}
sntImageViewPortrait.visibility = View.VISIBLE
sntImageViewLand.visibility = View.GONE
}
}

最新更新