为什么 Glide 加载的图像在 RecyclerView 中被降采样到低分辨率?

Why images loaded by Glide get downsampled to low resolution in a RecyclerView?

我在我的应用程序中从 Picasso 切换到 Glide。我有一个 RecyclerView,每一项都是 CustomView。这个CustomView根据不同的数据源动态添加TextViewImageView

A FillWidthImageView 用于显示这些图像,它会自动填充屏幕宽度。当我使用 Picasso 时,效果很好。但是,当我使用 Glide 加载图像时,显示在 FillWidthImageView 中的图像看起来像一个分辨率极低的马赛克,因为它被严重缩减采样。

如果我改用普通 ImageView,加载图像的大小与占位符相同,图像看起来仍然像马赛克。如果没有占位符,图像在屏幕上看起来很小。如果我在空白 Activity 中显示图像,它们将以全分辨率和正确尺寸加载。


在我的 CustomView 中添加 ImageView 的代码(扩展 LinearLayout),在 RecyclerView.onCreateViewHolder()

中调用
public void addImageView() {
    ImageView imageView = new FillWidthImageView(getContext());
    imageView.setPadding(0, 0, 0, 10);
    imageView.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
    addView(imageView);
}

代码FillWidthImageView

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    Drawable drawable = getDrawable();
    if (drawable != null) {
        int width = MeasureSpec.getSize(widthMeasureSpec);
        int diw = drawable.getIntrinsicWidth();
        if (diw > 0) {
            int height = width * drawable.getIntrinsicHeight() / diw;
            setMeasuredDimension(width, height);
        } else
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    } else
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}

加载图片的代码,在RecyclerView.onBindItemViewHolder()

中调用
Glide.with(getContext()).load(url).into(imageView);

与 Picasso 相比,Glide 加载的图像质量较差,因为 Glide 的默认位图格式设置为 RGB_565 并且与 ARGB_8888 相比,它仅消耗 50% 的内存占用。

如您在此 video.

中所见,这使得 Glide 比 Picasso 更快

好消息是您可以通过创建一个从 GlideModule 扩展的新 class 将位图格式切换为 ARGB_8888 :-

public class GlideConfiguration implements GlideModule {

    @Override
    public void applyOptions(Context context, GlideBuilder builder) {
        // Apply options to the builder here.
        builder.setDecodeFormat(DecodeFormat.PREFER_ARGB_8888);
    }

    @Override
    public void registerComponents(Context context, Glide glide) {
        // register ModelLoaders here.
    }
}

并在清单中添加元数据字段

<meta-data android:name="com.inthecheesefactory.lab.glidepicasso.GlideConfiguration"
            android:value="GlideModule"/>

您可以在 Glide wiki 的 glide 配置页面上阅读更多相关信息,当您从 Picasso 切换过来时,您会发现 this 有趣的读物

谢谢@Hitesh Kr Sahu,不过我已经自己解决了这个bug。这是因为 Glide 没有获得我的 CustomView 包装器的正确尺寸。我通过调用 .override(int,int).fitCenter() 应用维度解决了这个错误。我将屏幕的宽度和高度传递给它,因此它会根据屏幕尺寸进行缩放。