前言
今天使用ImageView.setColorFilter()方法的时候,在A界面改变一个drawable状态,其他B,C,D…若引用了这个drawable则会同样的进行状态改变,我想这应该是android的内存优化的机制,下面我先来简单整理梳理下知识。
点亮图标
如果常做应用App开发,通常会有一个图标点亮的功能需求。

改变当前图标的颜色,用于表示该操作处于某个状态。一般的操作,可能直接准备两张图片,不同状态对应相应的图片stateA<->imgA,stateB<->imgB。这里介绍另外一种实现的方法,
ImageView.setColorFilter()
Specify a color and Porter-Duff mode to be the color filter for this drawable.
imageView.getDrawable().setColorFilter(
ContextCompat.getColor(this, R.color.colorPrimary),
PorterDuff.Mode.SRC_IN);
上面两个都提到了PorterDuff,那这是什么呢?
PorterDuff.Mode
PorterDuff,一个陌生的单词,百度翻译和谷歌翻译都查无来处,原因在于它是一个组合词汇,来源于 Tomas Proter(托马斯波特)和 Tom Duff(汤姆达)两个名字。这俩人是在图形混合方面的大神级人物,他们在 1984 年发表了论文,第一次提出了图形混合的概念,也是取了两人的名字命名。Android PorterDuff.Mode 便是提供了图片的各种混合模式,可以分为两类:
Alpha compositing modes(由俩大神的定义,包含 alpha 通道因素)
Blending modes(不是俩大神的作品,不包含 alpha 通道因素)
具体的可以看官方文档对 PorterDuff.Mode的介绍。
简单来说,就是原图片source和目标图片desitination根据mode的配置合成一个新的图片,具体的Mode如下。

异常优化
因为Android的内存优化机制,若引用同一个drawable,在A界面改变一个drawable状态,其他B,C,D…若引用了这个drawable则会同样的进行状态改变。解决此问题需要用到Drawable类的mutate函数:
mutate()
A mutable drawable is guaranteed to not share its state with any other drawable.
此方法会拷贝一个drawable出来进行操作,更改状态后并不会到source drawable的任何属性,非常实用。
iconIv.getDrawable().mutate().setColorFilter(
ContextCompat.getColor(JMUITextActivity.this, R.color.colorPrimary),
PorterDuff.Mode.SRC_IN);
这篇博客介绍了如何使用ImageView.setColorFilter()和PorterDuff.Mode来改变图标颜色,实现点亮图标的效果。当在Android中多个界面引用同一drawable时,通过Drawable的mutate()方法避免状态改变同步,进行异常优化。
7384

被折叠的 条评论
为什么被折叠?



