【问题标题】:How to make ImageView on RecyclerView to have a dimension set while Glide is loading the image?如何在 Glide 加载图像时使 RecyclerView 上的 ImageView 设置尺寸?
【发布时间】:2016-10-05 05:07:49
【问题描述】:

我在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 的恒定像素宽度/高度,我可以让它在一部手机而不是另一部手机上工作。我不能以这种方式硬编码ImageView 大小。 Glide.override 似乎没有像我预期的那样工作。我需要我的ImageView 根据正在加载的图像的大小知道它的当前尺寸,以便它填充加载的片段之间的间隙并且不会突然消失。

有什么想法吗?

【问题讨论】:

    标签: android imageview android-imageview android-glide


    【解决方案1】:

    Glide 库不对此问题提供支持。我试过很多次。但是,最后我自己得出了一个解决方案。要加载图像,您必须发送图像的 URL 和更多元数据。

    解决方案是,您需要使用此元数据发送将要加载到您的 imageview 中的图像的尺寸(高度和宽度)。

    您将在图像加载到图像视图之前获得这些尺寸。现在,您需要使用这些尺寸缩放图像视图的高度和宽度,并为此应用占位符。

    最后,当您的图片被加载时,它将取代您的占位符。

    我假设您要设置图像视图的宽度 = 屏幕宽度

        DisplayMetrics metrics;
        int width = 0, height = 0;
    
    metrics = new DisplayMetrics();
    

    height = 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"
     />
    

    【讨论】:

    • 天哪,这行得通。但是我的缩放图像有点拉长,但效果却从未如此差。
    【解决方案2】:
    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;
    

    【讨论】:

      猜你喜欢
      • 2016-06-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-17
      • 2020-12-13
      相关资源
      最近更新 更多