解决Glide启用过渡时Placeholder变形问题
2018-05-15 本文已影响0人
WenHuayu
在项目中使用到了Glide图片加载库,但是在使用中遇到一些奇葩的现象,这里记录一下,如果大家也遇到相同的问题可以参考一下。
问题:当一次图片加载同时应用了placeholder占位符和crossFade过渡动画时,placeholder与图片的过渡非常不自然,有时候placeholder突变,有时候placeholder变形,十分影响视觉效果。
例如:
center.gif center_crop.gif center_inside.gif fit_center.gif- 图片加载成功之前placeholder样式不一,原因在于Glide是在成功加载图片之前,将placeholder作为普通图片设置到ImageView中的,所以placeholder会受ImageView的ScaleCrop属性影响,详见com.bumptech.glide.request.target.Target#onLoadStarted。
- 图片加载成功后开始过渡时placeholder有一次突变,原因在于placeholder与我们请求的图片过渡的时候,会将placeholder缩放至与请求的图片相同的尺寸。
解决的思路比较简单,既然placeholder会受到神秘力量的缩放,并且这种缩放是必然的,我们可以将其反向缩放相应大小,则最终的图片结果还是原来的配方,还是原来的味道。
自定义Drawable包装一下placeholder,重写draw()方法实现我们的目的,核心代码
public GlidePlaceholderDrawable(Bitmap resource) {
this.mHeight = resource.getHeight();
this.mWidth = resource.getWidth();
this.mResource = resource;
}
@Override
public void draw(@NonNull Canvas canvas) {
//canvas.getMatrix()这个方法已经@Deprecated了,但是这里要实现功能不得不用,缩放,位移啊,数据都在matrix里了
Matrix matrix = canvas.getMatrix();
matrix.getValues(mMatrixValues);
//由于缩放的中心是在左上角,而不是图片中心,故需要再平衡一下因为缩放造成的位移
mMatrixValues[Matrix.MTRANS_X] = ((canvas.getWidth() - mWidth) / 2 - mMatrixValues[Matrix.MTRANS_X]) / mMatrixValues[Matrix.MSCALE_X];
mMatrixValues[Matrix.MTRANS_Y] = ((canvas.getHeight() - mHeight) / 2 - mMatrixValues[Matrix.MTRANS_Y]) / mMatrixValues[Matrix.MSCALE_Y];
//尺寸反向缩放
mMatrixValues[Matrix.MSCALE_X] = 1 / mMatrixValues[Matrix.MSCALE_X];
mMatrixValues[Matrix.MSCALE_Y] = 1 / mMatrixValues[Matrix.MSCALE_Y];
matrix.setValues(mMatrixValues);
canvas.drawBitmap(mResource, matrix, mPaint);
}
改进版:
new_center.gif new_center_crop.gif new_center_inside.gif new_fit_center.gif同样的加载图片错误占位符也有相同的问题,都可以使用相同的方案解决
完整代码已经上传到我的Github啦,各位如果觉得有用,希望给个小星星:https://github.com/WenHuayu/GlidePlaceholderDrawable
快捷使用帮助:
Step 1. Add the JitPack repository to your build file
allprojects {
repositories {
...
maven { url 'https://jitpack.io' }
}
}
Step 2. Add the dependency
dependencies {
implementation 'com.github.WenHuayu:GlidePlaceholderDrawable:1.0.0'
}
Step 3. set placeholder
placeholder(new GlidePlaceholderDrawable(getResources(), R.drawable.placeholder)))