如何在 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;