Android background tint顏色渲染
該篇文章主要是講Android顏色渲染,首先先來看看PorterDuff,對繪圖非常重要。
PorterDuff的由來:
相信大多數人看到這個ProterDuff單詞很奇怪了吧,這腫麽個意思呢,然後就用有道啊,金山啊開始翻譯,但是翻譯軟件給出的結果肯定還是 ProterDuff或者”未找到”.
這是神馬情況呢?因為ProterDuff是兩個人名的組合: Tomas Proter和 Tom Duff. 他們是最早在SIGGRAPH上提出圖形混合概念的大神級人物.有興趣的童靴們可以自己查下並深入了解,在此不再做過多描述.
利用ProterBuff.Mode我們可以完成任意2D圖像測操作, 比如塗鴉畫板應用中的橡皮擦效果,繪制各種自定義的進度,等等很強大的效果,下面請看效果:
從上面我們可以看到PorterDuff.Mode為枚舉類,一共有16個枚舉值:
1.PorterDuff.Mode.CLEAR
所繪制不會提交到畫布上。
2.PorterDuff.Mode.SRC
顯示上層繪制圖片
3.PorterDuff.Mode.DST
顯示下層繪制圖片
4.PorterDuff.Mode.SRC_OVER
正常繪制顯示,上下層繪制疊蓋。
5.PorterDuff.Mode.DST_OVER
上下層都顯示。下層居上顯示。
6.PorterDuff.Mode.SRC_IN
取兩層繪制交集。顯示上層。
7.PorterDuff.Mode.DST_IN
取兩層繪制交集。顯示下層。
8.PorterDuff.Mode.SRC_OUT
取上層繪制非交集部分。
9.PorterDuff.Mode.DST_OUT
取下層繪制非交集部分。
10.PorterDuff.Mode.SRC_ATOP
取下層非交集部分與上層交集部分
11.PorterDuff.Mode.DST_ATOP
取上層非交集部分與下層交集部分
12.PorterDuff.Mode.XOR
異或:去除兩圖層交集部分
13.PorterDuff.Mode.DARKEN
取兩圖層全部區域,交集部分顏色加深
14.PorterDuff.Mode.LIGHTEN
取兩圖層全部,點亮交集部分顏色
15.PorterDuff.Mode.MULTIPLY
取兩圖層交集部分疊加後顏色
16.PorterDuff.Mode.SCREEN
取兩圖層全部區域,交集部分變為透明色
還有另外兩個
17.PorterDuff.Mode.ADD
18.PorterDuff.Mode.OVERLAY
那什麽是Tint呢?
我們可以通過xml中的屬性android:backgroundTint和android:backgroundTintMode來設置,android:backgroundTintMode這個屬性傳的值就是剛剛上面那些PorterDuff.Mode中的值,效果的話上面的圖也展示了。android:backgroundTint的話就是傳color的值。
那麽android:background和android:backgroundTint有什麽區別呢?
如果設置了android:background,那麽控件的背景顏色就會直接修改。
如果設置了android:backgroundTint,那麽就會將設置的顏色和原來的背景進行一個疊加的過程,至於如何疊加,就是上面的mode。
看一個例子:
<Button
android:id="@+id/button_1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/button_states"
android:text="text" />
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_pressed="true"
android:drawable="@drawable/button_pressed" />
<item
android:state_pressed="false"
android:drawable="@drawable/button_normal" />
</selector>
這是button正常顯示的樣子:
為button設置tint:
Button b = (Button)findViewById(R.id.button_1);
int tint = Color.parseColor("cyan");
b .getBackground().setColorFilter(tint, Mode.DARKEN);
- 1
看到了麽,效果是疊加,而不是直接覆蓋。使用tint可以保留原來的陰影波紋等效果。
還有個方法是setBackgroundTintList(ColorStateList)和setBackgroundTintMode(PorterDuff.Mode)方法。
如果控件沒有背景,設置backgroundTint無效。
Button b = (Button) findViewById(R.id.button_1);
b.setText(modes[i - 1]);
int[] colors = new int[]{0xfff8513f, 0xffe43d2b};
int[][] states = new int[2][];
states[0] = new int[]{android.R.attr.state_pressed};
states[1] = new int[]{android.R.attr.state_enabled};
b.setBackgroundTintList(new ColorStateList(states, colors));
b.setBackgroundTintMode(mode[i - 1]);
- 1
效果與上面類似,但是多了狀態變換的顏色變換。
但是如果控件狀態轉換的時候,顏色不換,則可以采用
b .getBackground().setColorFilter(tint, Mode.DARKEN);
因為這個API在21版本上才有,對於低版本調用的話,可以調用以下方法:
ViewCompat.setBackgroundTintList(b, new ColorStateList(states, colors));
ViewCompat.setBackgroundTintMode(b, Mode.DARKEN);
但是現在普通的button,去調用setBackgroundTint和setBackgroundTintMode無效,沒有什麽效果。解決這種問題,可以通過使用android.support.v7.widget.AppCompatButton,然後調用setSupportBackgroundTintList以及setSupportBackgroundTintMode方法。
Android background tint顏色渲染