public static void initImageWithFileCache(Context context, String url, ImageView imageView) {
GlideApp.with(context)
.load(url)
.placeholder(R.mipmap.banner_loading)
.error(R.mipmap.banner_loading_error)
.transition(DrawableTransitionOptions.withCrossFade(100)
.diskCacheStrategy(DiskCacheStrategy.ALL)
.skipMemoryCache(false)
.dontAnimate()
.fitCenter()
.into(imageView);
我总结了一下此问题的解决方式,除了一些通用的解决方式之外,主要体现还是体现在动画
和 position
、tag
俩方面
针对一些基础设置,可能有效,也可能无效,但肯定不会产生新的问题 ~
常规加载图片时传入的上下文大多为当前上下文,这里我们采用Application全局的上下文,如没有的话就写个新类extend一下Application,然后出个返回上下文的方法就行 ~
查看Glide加载时是否有设置 skipMemoryCache
相关属性,此部分主要判断用户是否设置内存缓存,如true则为跳过,所以记得false ~
.skipMemoryCache(false)
动画方面主要涉及RecyclerView的自带动画和Glide的自带动画 ~
RecyclerView
默认设置了自带的动画效果,也就是DefaultItemAnimator
默认动画类,同时在内部设置动画主要为animateChangeImpl
方法,可以从下图中看出图片闪烁的原因很大可能是 animateChangeImpl()
方法中 alpha
(透明动画)的实现导致的,所以我们可以将此类复制出来重新进行设置,具体如下 ~
亲试,无效,可跳过!!!
- 通过
Ctrl+Shift+F
搜索 animateChangeImpl()
方法,然后找到 DefaultItemAnimator
类 - 将
DefaultItemAnimator
类整体复制到一个新建类中,但是要记得删除图中俩处标记的alpha
设置 RecyclerView
通过 setItemAnimator
重新设置动画效果,如下 ~
mRv.setItemAnimator(new 新建动画类());
不推荐:亲试,有效,虽然闪烁场景较少,但是依旧存在闪烁问题,故有效性较低 ~
((DefaultItemAnimator) mRv.getItemAnimator()).setSupportsChangeAnimations(false);
这里主要调用Glide
中的 dontAnimate()
方法用于取消 Glide
的动画效果 ~
GlideApp.with(context)
.load(url)
.placeholder(R.mipmap.banner_loading)
.error(R.mipmap.banner_loading_error)
.diskCacheStrategy(DiskCacheStrategy.ALL)
.dontAnimate()
.fitCenter()
.into(imageView);
此方式主要是通过帮每个 postion
做标记,跳过常规的每次加载 ~
为 RecyclerView
标记Tag,主要判别 url 是否改变,从而判别 ImageView
是否需要重新加载,但是仅做此设置会导致数据项重复!
setHasStableIds(true);
So Here:
adapter里面重写 getItemId 即可解决数据项重复的问题 ~
@Override
public long getItemId(int position) {
return position;
逻辑比较简单,首次加载ImageView通过tag判断是否加载过,如已加载过则不进行二次加载,如为首次加载则做个tag标记 ~ (无用)
public static void initImageWithFileCache(Context context, String url, ImageView imageView) {
if (!url.equals(imageView.getTag())) {
imageView.setTag(null);
GlideApp.with(context)
.load(url)
.placeholder(R.mipmap.banner_loading)
.error(R.mipmap.banner_loading_error)
.diskCacheStrategy(DiskCacheStrategy.ALL)
.dontAnimate()
.skipMemoryCache(false)
.fitCenter()
.into(imageView);
imageView.setTag(url);
场景商未遇到,仅做记录,借鉴与此
import com.bumptech.glide.load.model.GlideUrl;
import com.bumptech.glide.load.model.Headers;
import java.net.URL;
import java.util.Map;
public class IMTokenGlideUrl extends GlideUrl {
private int mHashCode;
public IMTokenGlideUrl(URL url) {
super(url);
public IMTokenGlideUrl(String url) {
super(url);
public IMTokenGlideUrl(URL url, Headers headers) {
super(url, headers);
public IMTokenGlideUrl(String url, Headers headers) {
super(url, headers);
@Override
public boolean equals(Object o) {
if (o instanceof GlideUrl) {
GlideUrl other = (GlideUrl) o;
return getCacheKey().equals(other.getCacheKey())
&& !mapCompare(getHeaders(), other.getHeaders());
return false;
@Override
public int hashCode() {
if (mHashCode == 0) {
mHashCode = getCacheKey().hashCode();
if (getHeaders() != null) {
for (String s : getHeaders().keySet()) {
if (getHeaders().get(s) != null) {
mHashCode = 31 * mHashCode + getHeaders().get(s).hashCode();
return mHashCode;
private static boolean mapCompare(Map<String, String> map1, Map<String, String> map2) {
boolean differ = false;
if (map1 != null && map2 != null) {
if (map1.size() == map2.size()) {
for (Map.Entry<String, String> entry1 : map1.entrySet()) {
String value1 = entry1.getValue() == null ? "" : entry1.getValue();
String value2 = map2.get(entry1.getKey()) == null ? "" : map2.get(entry1.getKey());
if (!value1.equals(value2)) {
differ = true;
break;
} else differ = map1 != null || map2 != null;
return differ;
场景尚未遇到,仅做记录,借鉴与此
闪烁原因:对于任何 Transformation
子类,包括 BitmapTransformation
,你都必须实现这三个方法,以使得磁盘和内存缓存正确地工作
equals()
hashCode()
updateDiskCacheKey
自定义圆角类(GlideRoundTransform)
public class GlideRoundTransform extends BitmapTransformation {
private final float radius;
private final String ID = "com. bumptech.glide.transformations.FillSpace";
private final byte[] ID_ByTES= ID.getBytes(CHARSET);
public GlideRoundTransform(int dp){
this.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 Bitmap roundCrop(BitmapPool pool, Bitmap toTransform) {
if (toTransform == null) {
return null;
Bitmap result = pool.get(toTransform.getWidth(), toTransform.getHeight(), Bitmap.Config.ARGB_8888);
if (result == null) {
return Bitmap.createBitmap(toTransform.getWidth(), toTransform.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(result);
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setShader(new BitmapShader(toTransform, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP));
RectF rectF = new RectF(0f, 0f, toTransform.getWidth(), toTransform.getHeight());
canvas.drawRoundRect(rectF, radius, radius, paint);
return result;
@Override
public boolean equals(Object o){
if (o instanceof GlideRoundTransform){
GlideRoundTransform other = (GlideRoundTransform) o;
return radius == other.radius;
return false;
@Override
public int hashCode() {
return Util.hashCode(ID.hashCode(),
Util.hashCode(radius));
@Override
public void updateDiskCacheKey(@NonNull MessageDigest messageDigest){
messageDigest.update(ID_ByTES);
byte[] radiusData =ByteBuffer.allocate(4).putInt((int) radius).array();messageDigest.update(radiusData);
Glide.with(mContext)
.load(url)
.apply(new RequestOptions()
.transform( new GlideRoundTransform(4)))
.placeholder(placeimg).fallback(placeimg)
.error(placeimg)
.into(imageView);
最近在开发中发现RecyclerView刷新列表(notifyDataSetChanged)时,如果使用的是Glide加载图片,那么会出现图片闪烁、图片变形的问题,针对于此有着千奇百怪的解决方案 ~首先我的问题已经解决,但是尝试了不少方式,特此做一下归纳 ~ 问题背景成功方式解决方式动画方面解决方式 一解决方式 二Tag问题背景每个人的场景可能不同,仅记录我的场景,解决方式可能通用,可一试列表控件:RecyclerView图片框架:Glide问题场景:购物车+、- 数据变化所遇问题:每次.
可能这个问题很常见,大家也有不少人解决了,大部分人用的方法一和二如果你还没解决的话,那么看这篇文章就对了
使用RecyclerView,Glide加载图片,当点击图片进行刷新,不管是局部刷新还是全部刷新的时候,都会使用glide重新加载图片,这时候如果glide加载图片的时候没设置好就会出现刷新的时候闪烁的问题,当然这是我出现的问题。
网上很多基本都是说recyclerview刷新闪烁是因...
最近开发使用Glide加载图片到RecyclerView的item中的ImageView,发现重新刷新时每个ImageView都会闪烁一下
在网上找了很多解决方案:
1.更改RecyclerView中的 DefaultItemAnimator 类中的 animateChangeImpl() 方法,去掉透明度变化
然后再将更改好的类设置给RecyclerView
发现没什么用
2....
1.关于忽大忽小:其实很大程度上是由于刷新闪烁问题引起的。
刚开始我并不知道这个原因,所以我一定追求固定宽高。解决方法如下:
用Gilde的resize(w,h)或是override(w,h),
又或是在布局xml文件中...
今天由于项目需求的原因, 需要把原来的ViewPager的长方形图片转成圆角图片.
一直觉得Glide很强大, 应该可以直接设置圆角图片, 但是输入 . 之后并没有找到这个方法, 顿时一大片问号飘过 !!!
下面来说说遇到的问题:
1. 之前Glide 3.0+ 都是直接Glide. 点点点就行了, 现在升级到Glide 4.0+, 需要把这些配置全部写在RequestOptions这个方法...
可以尝试使用Glide的占位符(placeholder)和错误占位符(error placeholder)功能来解决这个问题。占位符是在加载网络图片之前,显示在ImageView中的临时图片,可以是任何本地资源文件或者通过URL加载的图片。如果Glide加载图片失败,它会尝试使用错误占位符来代替。这些占位符可以减少RecyclerView中图片加载的闪烁效果。
以下是一个使用Glide占位符和错误...
根据你提供的信息,我可以理解你遇到的问题是,当 Glide 加载图片失败时,会使用自定义 View 显示默认的头像,这会导致头像闪烁。为了解决这个问题,你可以考虑以下两个方案:
预加载头像
你可以在 Glide 加载图片之前,先使用 Glide 预加载默认头像,这样即使加载图片失败,也不会显示其他的 View,而是直接显示预加载的头像,从而避免了头像的闪烁问题。这个方案的具体实现方式可以参考 ...
一、简介:
介绍两种使用 BitmapTransformation 来实现 Glide 加载圆形图片和圆角图片的方法。Glide 并不能直接支持 Round Pictures ,需要使用 BitmapTransformation 来进行处理。
二、网上的实现方式
这里介绍下网上常见的方式和使用 RoundedBitmapDrawable 两种方法,本质上是差不多的:
使用 Canvas 和 Paint 来绘制
使用 Android.support.v4.graphics.drawable.RoundedBitmapDrawable
实现圆形图片:
* Glide 圆
在开发中其实不论前台、后台都会留一些后门,方便管理人员操作(有点超级权限的意思),但是这样的入口我们又不能让用户直接看到,所以就有一些芝麻开门的操作 ~
今天真是个好日子啊,2020.5.20, 计划终究还是赶不上变化 ~
后门效果长按监听 (原生版)长按时长监听(乞丐版)长按时长监听(主推:土豪版)长按时长监听使用方式规定时间,点击次数(主推:土豪版)基于实践 - Demo监听方式MainActivityactivity_main
长按监听 (原生版)
Android系统自带的一种长按监
android实现程序开机自启动
在安卓中,想要实现app开机自动启动,需要实现拦截广播android.permission.RECEIVE_BOOT_COMPLETED,并且需要使用静态注册广播的方法(即在AndroidManifest.xml文件中定义广播)
1、先在AndroidManifest.xml文件中定义广播和声明权限
在这个例子中,我们使用 RequestOptions 的 disallowHardwareConfig() 方法关闭硬件加速,然后将这个 options 对象传递给 Glide 的 apply() 方法。
3.使用 Bitmap 转换器
你可以使用 Glide 的 Bitmap 转换器来对加载的图片进行处理。具体实现方法如下:
```java
Glide.with(this)
.asBitmap()
.load(imageUrl)
.apply(new RequestOptions()
.transform(new BlurTransformation(25)))
.into(imageView);
在这个例子中,我们使用 RequestOptions 的 transform() 方法来添加一个 Bitmap 转换器,这里使用了一个模糊转换器来对图片进行模糊处理。
以上是一些解决 Glide 加载图片文字模糊的方法,你可以根据实际情况来选择使用哪种方法。