如何在Glide加载图像时使RecyclerView上的ImageView具有尺寸设置?

问题描述:

我在我的RecyclerView里面有一些关于ImageView的问题。我正在创建漫画查看器,并加载非常长的图像。我把我的图片切成8部分,所以我的ImageView可以处理它们。问题是在RecyclerView上加载图像时。如何在Glide加载图像时使RecyclerView上的ImageView具有尺寸设置?

我使用的是Glide,当Glide正在加载分段部件时,会有相当明显的延迟。由于图像缓存,这是可取的,并且它工作得很好,但是它留下了不希望的效果。我不能表现出实际的图像,因为它正在发生非常快,但我可以用ASCII代表它:

例如,这里是我RecyclerView在启动时:

---------------Segment1 
#......................... 
#......................... 
#......................... 
#......................... 
#......................... 
#......................... 
---------------Segment2 
---------------Segment3 
---------------Segment4 
#......................... 
#......................... 
#......................... 
#......................... 
#......................... 
#......................... 

正如你可以在这里看到,滑翔是尚未完成加载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); 
} 

如果我分配基于ImageView恒定像素宽度/高度通过getLayoutParams(),我可以让它在一部手机上工作,而不是另一部手机上。我不能这样硬编码ImageView大小。 Glide.override似乎没有按照我的预期工作。我需要我的ImageView根据所加载图像的大小了解其当前尺寸,以便填充已加载段之间的间隙,而不是弹出存在。

有什么想法?

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

解决的办法是,用这种元数据需要发送这是会在您的ImageView要加载的图像的尺寸(高度和宽度)。

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

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

我假设你要设置你的ImageView的宽度=屏幕的宽度

DisplayMetrics metrics; 
    int width = 0, height = 0; 

metrics = new DisplayMetrics(); 

高度= metrics.heightPixels; width =度量。像素宽度;

现在,

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" 
/> 
+0

耶稣基督这个工作。但我缩放的图像有点拉长,但从来没有它的工作。 –

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;