如何在 Glide 加载图像时使 RecyclerView 上的 ImageView 具有尺寸集?
How to make ImageView on RecyclerView to have a dimension set while Glide is loading the image?
我的 RecyclerView
中的 ImageView 有一些问题。我正在创建一个漫画查看器并加载很长的图像。我将我的图像切成 8 部分,以便我的 ImageView
可以处理它们。问题是在 RecyclerView
上加载图像时出现的问题。
我正在使用 Glide
,当 Glide
加载分段部分时,有相当明显的延迟。由于图像缓存,这是更可取的,它工作得很好,但它留下了不良影响。我无法显示实际图像,因为它发生得非常快,但我可以使用 ASCII
:
来表示它
例如,这是我的 RecyclerView
启动时:
---------------Segment1
#.........................
#.........................
#.........................
#.........................
#.........................
#.........................
---------------Segment2
---------------Segment3
---------------Segment4
#.........................
#.........................
#.........................
#.........................
#.........................
#.........................
正如您在这里注意到的,Glide 尚未完成加载 Segment2 和 Segment3,实际上,显示的是拼接在一起的 Segment1 和 Segment4。 Segment2 和 Segment3 突然消失了,这不是很好。
即使我把它放在一个ScrollView
上,然后动态添加ImageView
进去,也是一样的效果。由于显而易见的原因,我无法在 ImageView
上分配常量 px/dip 的宽度和高度,因为我需要处理多种屏幕尺寸。
我的 ImageView
设置如下所示:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/imageview_comic"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scaleType="fitXY"
android:adjustViewBounds="true"/>
</LinearLayout>
这是我绑定到这个 ImageView
:
时所做的事情
private void bindSegment(ComicViewHolder holder, int position)
{
File file = mSegments.get(position);
Point imageSize = Constants.getImageSize(file);
Point screenSize = Constants.getScreenSize(mContext);
ImageView imageView = holder.mImageViewComic;
Glide.with(imageView.getContext())
.load(file.getAbsolutePath())
.override(imageSize.x , imageSize.y)
.crossFade(0)
.into(imageView);
}
如果我通过 getLayoutParams()
基于 ImageView
分配一个常量像素 width/height,我可以让它在一个 phone 而不是另一个上工作。我不能用这种方式硬编码 ImageView
大小。 Glide.override
似乎没有像我预期的那样工作。我需要我的 ImageView
根据正在加载的图像的大小知道它的当前尺寸,以便它填充加载的片段之间的间隙而不是突然消失。
有什么想法吗?
Glide 库没有为这个问题提供支持。我试过很多次了。但是,最后我自己得出了一个解决方案。要加载图像,您必须发送图像的 URL 和更多元数据。
解决方案是,使用此元数据,您需要发送将要加载到图像视图中的图像的尺寸(高度和宽度)。
您将在图像加载到图像视图之前获得这些尺寸。现在,您需要使用这些尺寸缩放图像视图的高度和宽度,并为此应用占位符。
最后当您的图像被加载时,它将取代您的占位符。
我假设您要设置图像视图的宽度 = 屏幕宽度
DisplayMetrics metrics;
int width = 0, height = 0;
metrics = new DisplayMetrics();
身高=metrics.heightPixels;
宽度 = metrics.widthPixels;
现在,
int heightOfImage = 0;
int widthOfImage = 0;
float scalingRatio = ((Float.parseFloat(heightOfImage) / Float.parseFloat(widthOfImage));
viewHolder.imageLoadingLayout.getLayoutParams().height = Math.round(scalingRatio*width ); //imageLoadingLayout is your placeholder
最后,
Glide.with(activity)
.load(imageURL)
.diskCacheStrategy(DiskCacheStrategy.NONE)
.skipMemoryCache(true)
.listener(new RequestListener<String, GlideDrawable>() {
@Override
public boolean onException(Exception e, String model, Target<GlideDrawable> target, boolean isFirstResource) {
return false;
}
@Override
public boolean onResourceReady(GlideDrawable resource, String model, Target<GlideDrawable> target, boolean isFromMemoryCache, boolean isFirstResource) {
viewHolder.imageLoadingLayout.setVisibility(View.GONE);
return false;
}
})
.crossFade()
.override(1700, 1700)
.diskCacheStrategy(DiskCacheStrategy.ALL)
.into(imageView);
}
图像布局
<ImageView
android:id="@+id/imageView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:adjustViewBounds="true"
android:scaleType="fitCenter"
/>
newPostHolder.height = DeviceHight;
int heightOfImage = data.getInt("image_height");
if (heightOfImage > ((newPostHolder.height / 100) * 80) || heightOfImage == newPostHolder.height) {
heightOfImage = ((newPostHolder.height / 100) * 69);
}
newPostHolder.one_imageview.getLayoutParams().height = heightOfImage;
我的 RecyclerView
中的 ImageView 有一些问题。我正在创建一个漫画查看器并加载很长的图像。我将我的图像切成 8 部分,以便我的 ImageView
可以处理它们。问题是在 RecyclerView
上加载图像时出现的问题。
我正在使用 Glide
,当 Glide
加载分段部分时,有相当明显的延迟。由于图像缓存,这是更可取的,它工作得很好,但它留下了不良影响。我无法显示实际图像,因为它发生得非常快,但我可以使用 ASCII
:
例如,这是我的 RecyclerView
启动时:
---------------Segment1
#.........................
#.........................
#.........................
#.........................
#.........................
#.........................
---------------Segment2
---------------Segment3
---------------Segment4
#.........................
#.........................
#.........................
#.........................
#.........................
#.........................
正如您在这里注意到的,Glide 尚未完成加载 Segment2 和 Segment3,实际上,显示的是拼接在一起的 Segment1 和 Segment4。 Segment2 和 Segment3 突然消失了,这不是很好。
即使我把它放在一个ScrollView
上,然后动态添加ImageView
进去,也是一样的效果。由于显而易见的原因,我无法在 ImageView
上分配常量 px/dip 的宽度和高度,因为我需要处理多种屏幕尺寸。
我的 ImageView
设置如下所示:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/imageview_comic"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scaleType="fitXY"
android:adjustViewBounds="true"/>
</LinearLayout>
这是我绑定到这个 ImageView
:
private void bindSegment(ComicViewHolder holder, int position)
{
File file = mSegments.get(position);
Point imageSize = Constants.getImageSize(file);
Point screenSize = Constants.getScreenSize(mContext);
ImageView imageView = holder.mImageViewComic;
Glide.with(imageView.getContext())
.load(file.getAbsolutePath())
.override(imageSize.x , imageSize.y)
.crossFade(0)
.into(imageView);
}
如果我通过 getLayoutParams()
基于 ImageView
分配一个常量像素 width/height,我可以让它在一个 phone 而不是另一个上工作。我不能用这种方式硬编码 ImageView
大小。 Glide.override
似乎没有像我预期的那样工作。我需要我的 ImageView
根据正在加载的图像的大小知道它的当前尺寸,以便它填充加载的片段之间的间隙而不是突然消失。
有什么想法吗?
Glide 库没有为这个问题提供支持。我试过很多次了。但是,最后我自己得出了一个解决方案。要加载图像,您必须发送图像的 URL 和更多元数据。
解决方案是,使用此元数据,您需要发送将要加载到图像视图中的图像的尺寸(高度和宽度)。
您将在图像加载到图像视图之前获得这些尺寸。现在,您需要使用这些尺寸缩放图像视图的高度和宽度,并为此应用占位符。
最后当您的图像被加载时,它将取代您的占位符。
我假设您要设置图像视图的宽度 = 屏幕宽度
DisplayMetrics metrics;
int width = 0, height = 0;
metrics = new DisplayMetrics();
身高=metrics.heightPixels; 宽度 = metrics.widthPixels;
现在,
int heightOfImage = 0;
int widthOfImage = 0;
float scalingRatio = ((Float.parseFloat(heightOfImage) / Float.parseFloat(widthOfImage));
viewHolder.imageLoadingLayout.getLayoutParams().height = Math.round(scalingRatio*width ); //imageLoadingLayout is your placeholder
最后,
Glide.with(activity)
.load(imageURL)
.diskCacheStrategy(DiskCacheStrategy.NONE)
.skipMemoryCache(true)
.listener(new RequestListener<String, GlideDrawable>() {
@Override
public boolean onException(Exception e, String model, Target<GlideDrawable> target, boolean isFirstResource) {
return false;
}
@Override
public boolean onResourceReady(GlideDrawable resource, String model, Target<GlideDrawable> target, boolean isFromMemoryCache, boolean isFirstResource) {
viewHolder.imageLoadingLayout.setVisibility(View.GONE);
return false;
}
})
.crossFade()
.override(1700, 1700)
.diskCacheStrategy(DiskCacheStrategy.ALL)
.into(imageView);
}
图像布局
<ImageView
android:id="@+id/imageView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:adjustViewBounds="true"
android:scaleType="fitCenter"
/>
newPostHolder.height = DeviceHight; int heightOfImage = data.getInt("image_height"); if (heightOfImage > ((newPostHolder.height / 100) * 80) || heightOfImage == newPostHolder.height) { heightOfImage = ((newPostHolder.height / 100) * 69); } newPostHolder.one_imageview.getLayoutParams().height = heightOfImage;