1. 程式人生 > >Android background tint顏色渲染

Android background tint顏色渲染

背景顏色 roc replace 軟件 效果 sch per process 兩層

該篇文章主要是講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顏色渲染