A record of a pit step on Glide4

If you use the image loading library to load the image directly, you don't need to do any processing, then, in fact, most of the time, it doesn't make much difference if you use any loading library. Once you need to deal with all kinds of pictures, you will encounter all kinds of problems. Here is a record of a question about Glide, all of them are Glide 4.9 version.
Loading images in Glide can be very simple, similar to this:

   Glide.with(context)
      .load(url)
      .into(imageView);

But, when you process the image before loading it, what can we do? For example, for my requirements, the left side is loaded when it is displayed for the first time, and the right side is loaded after clicking it. Obviously, loading directly with Glide will not work. Here are some pits that have been stepped on.

Insert picture description here

1. Transformation

Through some built-in transformation classes, some processing effects can be achieved. For details , please refer to

   Glide.with(context)
      .load(url)
      .transform(new CircleCrop())
      .into(imageView);

Of course, you can also customize some means to achieve the goal. For details , please refer to

import android.graphics.Bitmap;
import android.support.annotation.NonNull;

import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool;
import com.bumptech.glide.load.resource.bitmap.BitmapTransformation;

import java.security.MessageDigest;

/**
 * Created by JayChou on 2019/3/5.
 */
public class GlideSelectIcon extends BitmapTransformation {
    
    
    private static final String ID = "yourpackagename.GlideSelectIcon";
    private static final byte[] ID_BYTES = ID.getBytes(CHARSET);

    private boolean isSelect = false;

    @Override
    protected Bitmap transform(@NonNull BitmapPool pool, @NonNull Bitmap toTransform, int outWidth, int outHeight) {
    
    
        Bitmap bitmap;
        if (isSelect) {
    
    
            bitmap = Bitmap.createBitmap(toTransform, toTransform.getWidth() / 2, 0, toTransform.getWidth() / 2, toTransform.getHeight()); //对图片的高度的一半进行裁剪
        } else {
    
    
            bitmap = Bitmap.createBitmap(toTransform, 0, 0, toTransform.getWidth() / 2, toTransform.getHeight()); //对图片的高度的一半进行裁剪
        }
        pool.put(bitmap);
        return bitmap;
    }

    public boolean isSelect() {
    
    
        return isSelect;
    }

    public void setSelect(boolean select) {
    
    
        isSelect = select;
    }

    @Override
    public boolean equals(Object o) {
    
    
        return o instanceof GlideSelectIcon;
    }

    @Override
    public int hashCode() {
    
    
        return ID_BYTES.hashCode();
    }

    @Override
    public void updateDiskCacheKey(@NonNull MessageDigest messageDigest) {
    
    
        messageDigest.update(ID_BYTES);
    }
}
   Glide.with(context)
      .load(url)
      .transform(new GlideSelectIcon())
      .into(imageView);

It should be noted that the above method is directly processed out of the picture, updateDiskCacheKeyand hashCode, and equalsjust help you deal with the cache key. If you need to handle caching by yourself, just update these places. If you only need to cache the original image, you can use .diskCacheStrategy(DiskCacheStrategy.RESOURCE)the strategy.

There is a pit to note here is that if you are not updating the cache, BitmapTransformation.transform()this method will not be used, which means that this method will only be used when the cache is loaded and updated for the first time, so this is a one-time The effect of treatment. But updating the cache every time is too much traffic, what else can be done?

2. Target transformation

My requirement happens to be to update one side of the picture every time, but I don’t want to refresh the cache every time, so what should I do? You can use the image processing method after loading ViewTarget.

import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.PixelFormat;
import android.graphics.drawable.Drawable;
import android.support.annotation.Nullable;
import android.widget.ImageView;

import com.bumptech.glide.Glide;
import com.bumptech.glide.request.target.DrawableImageViewTarget;

/**
 * Created by JayChou on 2019/3/6.
 */
public class GlideSelectDrawableImageViewTarget extends DrawableImageViewTarget {
    
    

    private boolean isSelect = false;

    public GlideSelectDrawableImageViewTarget(ImageView view, boolean isSelect) {
    
    
        super(view);
        Glide.with(view).clear(view);
        this.isSelect = isSelect;
    }

    @Override
    protected void setResource(@Nullable Drawable resource) {
    
    
        if (resource != null) {
    
    
            Bitmap toTransform = drawableToBitmap(resource);
            Bitmap bitmap;
            if (isSelect) {
    
    
                bitmap = Bitmap.createBitmap(toTransform, toTransform.getWidth() / 2, 0, toTransform.getWidth() / 2, toTransform.getHeight()); //对图片的高度的一半进行裁剪
            } else {
    
    
                bitmap = Bitmap.createBitmap(toTransform, 0, 0, toTransform.getWidth() / 2, toTransform.getHeight()); //对图片的高度的一半进行裁剪
            }
            view.setImageBitmap(bitmap);
        }
    }

    public Bitmap drawableToBitmap(Drawable drawable) {
    
    
        // 取 drawable 的长宽
        int w = drawable.getIntrinsicWidth();
        int h = drawable.getIntrinsicHeight();

        // 取 drawable 的颜色格式
        Bitmap.Config config = drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888
                : Bitmap.Config.RGB_565;
        // 建立对应 bitmap
        Bitmap bitmap = Bitmap.createBitmap(w, h, config);
        // 建立对应 bitmap 的画布
        Canvas canvas = new Canvas(bitmap);
        drawable.setBounds(0, 0, w, h);
        // 把 drawable 内容画到画布中
        drawable.draw(canvas);
        return bitmap;
    }
}

Then add it to Glide.

   Glide.with(context)
      .load(url)
      .transform(new GlideSelectDrawableImageViewTarget(imageView,true))
      .into(imageView);

What needs to be explained here is:
because I used DrawableImageViewTargetit, I changed drawableit Bitmapto deal with it by myself , you can also deal with it directly drawable.

Every time I have called it Glide.with(view).clear(view);, is because Glide added ViewTargetlater, will do multiplexing reference for the current imageView, so unless you manually clean again ImagView references, whether by each new setting ViewTargetwill not work, only Reuse the last one ViewTarget.

I have stepped on the pits for a long time, and it has been strange that setResourcethere isSelecthas been no change in the middle. It took a long time to find out here. The explanation about this paragraph is here .
Insert picture description here


The first is stuck because of the cache problem, and the second is because the object reference is stuck. The above is about the record of this time Glide stepping on the pit, on the importance of reading and understanding the official documents.

Guess you like

Origin blog.csdn.net/Ser_Bad/article/details/88237163