無(wú)意中 Get 一個(gè)新技能
公司的移動(dòng)端應(yīng)用伴箩,最近要換一個(gè) UI 主題色恰力,在更換一個(gè)圖片控件的選中與未選中效果時(shí)捻艳,本以為需要 UI 配合給新顏色切圖的,然而并不是舆床,直接使用 setColorFilter() 改顏色就好了。
無(wú)知的我很開(kāi)心 get 了一個(gè)新技能嫁佳!
這件小事的詳情
現(xiàn)在挨队,有一個(gè)效果展示是這樣的,選中某個(gè)車(chē)型時(shí)蒿往,顯示選中的顏色盛垦,是主題色紅色。
現(xiàn)在熄浓,我們的產(chǎn)品和UI寶寶決定要把主題色改成藍(lán)色情臭,于是選中效果要像下面這樣:
看項(xiàng)目代碼的時(shí)候,然后很驚訝的發(fā)現(xiàn)圖片的原圖赌蔑,是這個(gè)樣子的:
樣式布局:
//UI布局
<ImageView
android:id="@+id/icon"
android:layout_width="85dp"
android:layout_height="38dp"
android:layout_marginTop="5dp"
tools:src="@drawable/icon_carlevel_race"
android:scaleType="fitCenter" />
代碼控制顏色顯示:
//定義選中的顏色
int checkColor = context.getResources().getColor(R.color.theme_red);
//當(dāng)選中該項(xiàng)時(shí)俯在,顯示選中顏色,否則顯示未選中顏色
viewHolder.icon.setColorFilter(selectPosition==position? checkColor :Color.TRANSPARENT);
于是針對(duì)這個(gè)控件改顏色的需求娃惯,就只需要修改 checkColor
修改成藍(lán)色就好了跷乐,這神奇的操作在很明顯在于 setColorFilter
這個(gè)方法,于是我點(diǎn)擊進(jìn)去趾浅,看到源碼中這個(gè)方法的實(shí)現(xiàn)愕提。
/**
* Set a tinting option for the image. Assumes
* {@link PorterDuff.Mode#SRC_ATOP} blending mode.
*
* @param color Color tint to apply.
* @attr ref android.R.styleable#ImageView_tint
*/
@RemotableViewMethod
public final void setColorFilter(int color) {
setColorFilter(color, PorterDuff.Mode.SRC_ATOP);
}
注釋說(shuō)明該方法可為 ImageView 設(shè)置著色選項(xiàng)馒稍。內(nèi)部實(shí)現(xiàn)是調(diào)用了該方法的重載方法,默認(rèn)參數(shù)是 PorterDuff.Mode.SRC_ATOP
,圖形混合渲染模型之一,此參數(shù)是圖片改變顏色實(shí)現(xiàn)的重點(diǎn)浅侨,下面簡(jiǎn)單介紹一下纽谒。
PorterDuff.Mode
PorterDuff,一個(gè)陌生的單詞如输,百度翻譯和谷歌翻譯都查無(wú)來(lái)處鼓黔,原因在于它是一個(gè)組合詞匯,來(lái)源于 Tomas Proter(托馬斯波特)和 Tom Duff(湯姆達(dá))兩個(gè)名字不见。這倆人是在圖形混合方面的大神級(jí)人物,他們?cè)?1984 年發(fā)表了論文澳化,第一次提出了圖形混合的概念,也是取了兩人的名字命名稳吮。
Android PorterDuff.Mode 便是提供了圖片的各種混合模式缎谷,可以分為兩類(lèi):
- Alpha compositing modes(由倆大神的定義,包含 alpha 通道因素)
- Blending modes(不是倆大神的作品灶似,不包含 alpha 通道因素)
具體的可以看官方文檔對(duì) PorterDuff.Mode
的介紹列林,我這里只說(shuō)涉及到的 SRC_ATOP
。
既然混合酪惭,兩個(gè)圖片席纽,源圖片和目標(biāo)圖片,如下:
SRC_ATOP 混合模式效果如下圖撞蚕,只保留源圖片和目標(biāo)圖片的相交部分润梯,其他部分舍棄:
按照上面的示例來(lái)對(duì)應(yīng),那么我們的源圖就是藍(lán)色甥厦,目標(biāo)圖片是小汽車(chē)圖案纺铭。藍(lán)色和小汽車(chē)圖案的重合部分,只有線條刀疙,所以能達(dá)到改變顏色的效果舶赔。
那么,就算我們的小汽車(chē)圖片是任何顏色谦秧,都能達(dá)到不換圖片竟纳,改選中顏色的效果。
在這種簡(jiǎn)單的圖片顏色上疚鲤,合理使用 SetColorFilter() 锥累,可以為 UI 好搭檔節(jié)省了不少切圖工作量,而且集歇,同樣能縮小了 APK 的體積桶略。
最后
接手老項(xiàng)目的迭代開(kāi)發(fā),是十分奇妙的旅程,誰(shuí)知道下面等待著的是一個(gè)深坑還是華麗的騷操作际歼。
see you next blog ~