解决Glide加载图片闪烁的问题(感觉加载了两遍 !!!)

本文介绍如何使用Glide4.0+在Android应用中实现图片圆角效果,包括配置RequestOptions,自定义BitmapTransformation以及解决图片闪烁问题。

今天由于项目需求的原因, 需要把原来的ViewPager的长方形图片转成圆角图片.

一直觉得Glide很强大, 应该可以直接设置圆角图片, 但是输入 . 之后并没有找到这个方法, 顿时一大片问号飘过 !!!

下面来说说遇到的问题:

1. 之前Glide 3.0+ 都是直接Glide. 点点点就行了, 现在升级到Glide 4.0+, 需要把这些配置全部写在RequestOptions这个方法里.

例如: 

dontAnimate() //去掉动画, skipMemoryCache() //不使用缓存等

配置好后, 需要在Glide使用apply(options)方法

例如:

Glide.with(mContext)
       .load(url)
       .apply(options)
       .into(imageView);

2. 既然是要设置圆角, 那么肯定是要自己自定义来写了, 因此需要自己写个类继承 BitmapTransformation, 然后重写其中两个方法.

上代码:

注意: 注释部分一定要注意 !!!

自己搜到的基本是这些代码, 也显示圆角图片了,  但是又出现了一个新的问题.

3. Glide加载圆角图片, 第一张图片会闪烁 !!!

很无语!

一直认为Glide很强大, 肯定有设置圆角的方法,  经过一段时间的源码查找,  还真找到了 --> 

new RoundedCorners(16); //就是那么简单,  这个鬼难找

使用了这句代码, 运行了还真没闪烁, 点击去源码看了一下, 主要是这些区别:

仿照源码写了一下, 加进去, 运行果然没有闪烁, 很开森!!!

具体什么原因, 还没有研究出来, 很悲哀.

虽然不知道什么原因, 功能解决了, 还是可以了, 特此记录一下.

在使用 Glide 加载大图时,图片闪烁是一个较为常见的问题,尤其是在 RecyclerView 或 ListView 等可复用视图组件中。该问题通常与 Glide加载机制、图片缓存策略、以及视图的复用机制有关。 ### 原因分析 1. **视图复用机制** 在 RecyclerView 或 ListView 中,视图(如 ImageView)会被重复利用以提高性能。当一个图片加载完成时,目标视图可能已经被复用给另一个位置的条目,导致图片显示到错误的位置[^2]。 2. **Glide 的缓存机制** Glide 默认会从内存缓存或磁盘缓存中读取图片资源。如果图片没有被正确缓存,或者加载顺序被打乱,可能会导致图片多次加载,从而引发闪烁现象。 3. **未设置占位符或加载监听器** 如果没有设置 `.placeholder()` 或者没有在 `SimpleTarget` 中处理加载状态,图片加载完成前可能显示空白,加载完成后突然显示图片,造成视觉上的闪烁。 4. **图片尺寸过大或未进行缩放处理** 加载未经压缩或缩放的大图会增加内存压力和绘制时间,可能导致图片在绘制过程中出现短暂空白或闪烁。 --- ### 解决方案 1. **使用 `.placeholder()` 设置加载占位图** 在 Glide 请求链中直接设置占位图可以避免图片加载完成前出现空白状态,从而减少闪烁现象。 ```java Glide.with(context) .load(imageUrl) .placeholder(R.drawable.placeholder_image) .into(imageView); ``` 2. **使用 `.override()` 缩放图片尺寸** 避免加载原始大图,通过 `.override()` 指定目标尺寸,让 Glide 自动进行缩放,减少内存消耗和绘制延迟。 ```java Glide.with(context) .load(imageUrl) .override(1080, 720) // 设置目标尺寸 .placeholder(R.drawable.placeholder_image) .into(imageView); ``` 3. **使用 `.diskCacheStrategy()` 控制缓存策略** 对于大图加载,建议强制 Glide 使用磁盘缓存,以减少重复网络请求和加载延迟。 ```java Glide.with(context) .load(imageUrl) .diskCacheStrategy(DiskCacheStrategy.ALL) .placeholder(R.drawable.placeholder_image) .into(imageView); ``` 4. **使用 `SimpleTarget` 监听加载状态并精确控制显示** 如果需要更精细的控制,可以使用 `SimpleTarget` 来监听加载状态,并在 `onStart()`、`onResourceReady()` 等回调中设置占位图或图片资源,确保视图状态同步[^1]。 ```java Glide.with(context) .load(imageUrl) .asBitmap() .into(new SimpleTarget<Bitmap>() { @Override public void onResourceReady(Bitmap resource, GlideAnimation<? super Bitmap> glideAnimation) { imageView.setImageBitmap(resource); } @Override public void onStart() { imageView.setImageResource(R.drawable.loading); } @Override public void onLoadFailed(Exception e, Drawable errorDrawable) { imageView.setImageResource(R.drawable.error_image); } }); ``` 5. **避免视图复用导致的错位** 确保在 `onBindViewHolder()` 或 `getView()` 中每次绑定数据时都重置 ImageView 的内容,例如设置默认图片或清除之前的 Glide 加载。 ```java Glide.clear(imageView); imageView.setImageResource(R.drawable.default_image); ``` 6. **使用 `.transition()` 添加加载动画** 通过设置过渡动画,可以让图片加载过程更平滑,减少视觉上的闪烁感。 ```java Glide.with(context) .load(imageUrl) .transition(DrawableTransitionOptions.withCrossFade()) .into(imageView); ``` --- ###
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值