当前位置: 首页 > 工具软件 > glide-docs-cn > 使用案例 >

glide scaletype 无效_Android glide使用过程中遇到的坑(进阶篇)

龚沛
2023-12-01

之前有写过一篇关于glide的基本使用和相关配置,这篇就给大家分享一下glide在项目中通常会遇到的一些坑及解决方法

目前glide版本已经升级到了4.7.1,所以之前在用3.x版本的朋友,升级到最新版本的Api会有一些不一样的地方,详细不同地方可以参考官方介绍 https://muyangmin.github.io/glide-docs-cn/doc/migrating.html

最新版本配置环境:

implementation 'com.github.bumptech.glide:glide:4.7.1'

annotationProcessor 'com.github.bumptech.glide:compiler:4.7.1'

下面就来看看使用过程中遇到的坑,以下代码都是使用glide 4.7.1的api ,大家注意下。

当后台把用户的头像用地址前缀加用户ID拼接设计成时,往往修改头像后,再用Glide加载会发现头像还是之前的头像,原因很简单,是由于Glide默认加载了缓存的图片,所以导致更改之后地址没变还是加载之前的图片,如需要不加载缓存图片,可以使用如下代码:

public static void display(ImageView imageView, String url) {

if (imageView == null) return;

Glide.with(imageView.getContext())

.load(url)

.apply(new RequestOptions()

.dontAnimate()

.skipMemoryCache(true)

.diskCacheStrategy(DiskCacheStrategy.NONE))

.into(imageView);

}

设置圆角图片时,正好布局文件中用到了自定义圆角控件,这时应该这样处理代码如下:

/**

* 设置圆角

* @param imageView

* @param path

* @param dp 圆角度数 90dp宽高一致时为圆形

*/

public static void displayRound(ImageView imageView, String url, int dp) {

RequestOptions options = new RequestOptions()

.diskCacheStrategy(DiskCacheStrategy.ALL)

.transforms(new CenterCrop(), new GlideRoundTransform(dp));

Glide.with(imageView.getContext()).load(url)

.apply(options)

.transition(new DrawableTransitionOptions().crossFade())

.into(imageView);

}

public class GlideRoundTransform extends BitmapTransformation {

private static float radius = 0f;

public GlideRoundTransform() {

this(4);

}

public GlideRoundTransform(int dp) {

radius = Resources.getSystem().getDisplayMetrics().density * dp;

}

@Override

protected Bitmap transform(@NonNull BitmapPool pool, @NonNull Bitmap toTransform, int outWidth, int outHeight) {

return roundCrop(pool, toTransform);

}

private static Bitmap roundCrop(BitmapPool pool, Bitmap source) {

if (source == null) return null;

Bitmap result = pool.get(source.getWidth(), source.getHeight(), Bitmap.Config.ARGB_8888);

if (result == null) {

result = Bitmap.createBitmap(source.getWidth(), source.getHeight(), Bitmap.Config.ARGB_8888);

}

Canvas canvas = new Canvas(result);

Paint paint = new Paint();

paint.setShader(new BitmapShader(source, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP));

paint.setAntiAlias(true);

RectF rectF = new RectF(0f, 0f, source.getWidth(), source.getHeight());

canvas.drawRoundRect(rectF, radius, radius, paint);

return result;

}

public String getId() {

return getClass().getName() + Math.round(radius);

}

@Override

public void updateDiskCacheKey(@NonNull MessageDigest messageDigest) {

}

}

加载大图时会有可能出现OOM,可以控制高宽尺寸来处理,高宽设置一个合理的尺寸即可

public static void display(ImageView imageView, String url) {

if (imageView == null) return;

Glide.with(imageView.getContext())

.load(url)

.apply(new RequestOptions()

.override(180, 180))

.into(imageView);

}

第一次加载图片可能会出现拉伸变形,设置.dontAnimate()取消动画即可解决

public static void display(ImageView imageView, String url) {

if (imageView == null) return;

Glide.with(imageView.getContext())

.load(url)

.apply(new RequestOptions().dontAnimate())

.into(imageView);

}

当占位图的ScaleType和图片的ScaleType不一致时,占位图和图片就会有一个ScaleType不对,怎么解决呢,我这边是通过listener巧妙的解决了这个问题,代码如下:

public static void display(ImageView imageView, String url) {

Glide.with(imageView.getContext()).load(url)

.listener(new SGlideRequestListener(imageView, ImageView.ScaleType.FIT_XY, ImageView.ScaleType.CENTER_CROP))

.transition(new DrawableTransitionOptions().crossFade())

.into(imageView);

}

static class SGlideRequestListener implements RequestListener {

private ImageView.ScaleType mPlaceScaleType;

private ImageView.ScaleType mActualScaleType;

private ImageView mImageView;

SGlideRequestListener(ImageView mImageView, ImageView.ScaleType placeScaleType, ImageView.ScaleType actualScaleType){

this.mPlaceScaleType = placeScaleType;

this.mActualScaleType = actualScaleType;

this.mImageView = mImageView;

mImageView.setScaleType(placeScaleType);

}

@Override

public boolean onException(Exception e, String model, Target target, boolean isFirstResource) {

mImageView.setScaleType(mPlaceScaleType);

return false;

}

@Override

public boolean onResourceReady(GlideDrawable resource, String model, Target target, boolean isFromMemoryCache, boolean isFirstResource) {

mImageView.setScaleType(mActualScaleType);

return false;

}

}

当需要提前预下载好图片, 可以使用preload()方法

public static void preloadImage(String url) {

if (TextUtils.isEmpty(url)) {

return;

}

Glide.with(SSTApplication.getContext())

.load(url)

.diskCacheStrategy(DiskCacheStrategy.ALL)

.preload();

}

当需要通过url获取缓存文件对象时

private static File getCachedFile(String url) {

if (TextUtils.isEmpty(url)) {

return null;

}

File localFile = DiskLruCacheWrapper.get(Glide.getPhotoCacheDir(SSTApplication.getContext()),

DiskCache.Factory.DEFAULT_DISK_CACHE_SIZE).get(new OriginalKey(url, EmptySignature.obtain()));

Logger.d(TAG,localFile!=null?localFile.getAbsolutePath():"null");

return localFile;

}

static class OriginalKey implements Key {

private final String id;

private final Key signature;

private OriginalKey(String id, Key signature) {

this.id = id;

this.signature = signature;

}

@Override

public boolean equals(Object o) {

if (this == o) {

return true;

}

if (o == null || getClass() != o.getClass()) {

return false;

}

OriginalKey that = (OriginalKey) o;

return id.equals(that.id) && signature.equals(that.signature);

}

@Override

public int hashCode() {

int result = id.hashCode();

result = 31 * result + signature.hashCode();

return result;

}

@Override

public void updateDiskCacheKey(MessageDigest messageDigest) throws UnsupportedEncodingException {

messageDigest.update(id.getBytes(STRING_CHARSET_NAME));

signature.updateDiskCacheKey(messageDigest);

}

}

根据url判断图片是否下载

File localFile = DiskLruCacheWrapper.get(Glide.getPhotoCacheDir(SSTApplication.getContext()),

DiskCache.Factory.DEFAULT_DISK_CACHE_SIZE).get(new OriginalKey(url, EmptySignature.obtain()));

return localFile!=null;

清除当前url的缓存

File localFile = DiskLruCacheWrapper.get(Glide.getPhotoCacheDir(SSTApplication.getContext()),

DiskCache.Factory.DEFAULT_DISK_CACHE_SIZE).get(new OriginalKey(url, EmptySignature.obtain()));

if(file != null)

file.delete();

通过自定义View实现Fresco的viewAspectRatio宽高比功能

public class SImageView extends AppCompatImageView {

private float mAspectRatio = 0;

public SImageView(Context context) {

this(context,null);

}

public SImageView(Context context, @Nullable AttributeSet attrs) {

this(context, attrs,0);

}

public SImageView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {

super(context, attrs, defStyleAttr);

init(attrs);

}

private void init(AttributeSet attrs) {

final TypedArray typedArray = getContext().obtainStyledAttributes(attrs, R.styleable.SImageView);

if(typedArray != null) {

if (typedArray.hasValue(R.styleable.SImageView_viewAspectRatio)) {

mAspectRatio = typedArray.getFloat(R.styleable.SImageView_viewAspectRatio,0);

}

typedArray.recycle();

}

}

public void setAspectRatio(float aspectRatio){

if(mAspectRatio != 0) {

mAspectRatio = aspectRatio;

requestLayout();

}

}

@Override

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

if(mAspectRatio != 0) {

int width = MeasureSpec.getSize(widthMeasureSpec);

int height = (int) (width / mAspectRatio);

heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);

}

super.onMeasure(widthMeasureSpec, heightMeasureSpec);

}

}

attrs.xml

布局文件中只要在SImageView设置app:viewAspectRatio属性即可,

如:

android:id="@+id/image"

android:layout_width="match_parent"

android:layout_height="wrap_content"

app:viewAspectRatio="2" />

OK, 以上就是我在项目中遇到的一些坑及解决方法,希望对大家有所帮助!

 类似资料: