引子
顏色漸變一般兩種方式(好像是廢話額,因為凡是涉及到特效或者動畫,基本都是兩種方式··)
一種是寫XML配置,一種是寫純代碼;下面分別就兩個種方式給出demo;
方式1
在drawable/目錄下創建一個文件gradient.xml,內容如下:
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<gradient android:angle="0" android:endColor="@android:color/holo_red_light" android:startColor="@android:color/holo_green_light" />
</shape>
然后給某個view指定background:
<View android:layout_width="@dimen/shape_width"
android:layout_height="@dimen/shape_width"
android:background="@drawable/gradient" />
實際效果如下:
上面的gradient,我們用了3個屬性:angle角度,startColor,endColor起始和結束的顏色;
起始結束顏色好理解,這里的這個angle,其實我們還可以指定為其他值,上面指定0 ,我們得到了一個從左到右的漸變;
此外還可以指定,
0 是從左到右漸變;45是從左下角向右上角漸變;90是從下到上,135是從右下角到左上角;180則是從右到左;(當然也可以是 -45,-90....)

優點:簡單有效。足以應付大部分的漸變需求;
缺點: 不夠靈活,不能滿足高級需求。而且不支持任意角度(很詭異,只支持45的倍數);
方式二
利用LinearGradient + Paint + 自定義View;
由於是純代碼實現,我就直接帖代碼了;重點看紅色文字部分;
1 package com.example.colorstudy; 2 3 import android.content.Context; 4 import android.content.res.TypedArray; 5 import android.graphics.Canvas; 6 import android.graphics.Color; 7 import android.graphics.LinearGradient; 8 import android.graphics.Paint; 9 import android.graphics.Shader; 10 import android.support.annotation.Nullable; 11 import android.util.AttributeSet; 12 import android.view.View; 13 14 public class GradientDemoView extends View { 15 16 public GradientDemoView(Context context) { 17 this(context, null); 18 } 19 20 public GradientDemoView(Context context, @Nullable AttributeSet attrs) { 21 this(context, attrs, 0); 22 } 23 24 public GradientDemoView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { 25 super(context, attrs, defStyleAttr); 26 initAttrs(context, attrs); 27 } 28 29 private int mode; 30 31 private void initAttrs(Context context, AttributeSet attrs) { 32 TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.GradientDemoView); 33 if (null != ta) { 34 mode = ta.getInteger(R.styleable.GradientDemoView_mode, 0); 35 } 36 } 37 38 @Override 39 protected void onDraw(Canvas canvas) { 40 super.onDraw(canvas); 41 42 int width = getWidth(); 43 int height = getHeight(); 44 45 int colorStart = Color.RED; 46 int color1 = Color.GREEN; 47 int colorEnd = Color.BLUE; 48 49 Paint paint = new Paint(); 50 51 //重點解析這里的漸變配置 52 /** 53 * Create a shader that draws a linear gradient along a line. 創建一個沿着"一條線"繪制線性漸變的着色器? 54 * 55 * @param x0 "一條線"開始位置的X - 這個坐標是以 左上角為原點,對哦,android里面所有的繪制都是以控件左上角為原點(0,0) 56 * @param y0 "一條線"開始位置的Y 57 * @param x1 "一條線"結束為止的X 58 * @param y1 "一條線"結束為止的Y 59 * @param colors 顏色數組,可以是3個以上 60 * @param positions 顏色分段權重:比如說,有3種顏色,紅綠藍漸變,這里的positions的值是new float[]{0, 0.75f, 1f}; 61 * 則,0到0.75這一段,是紅色漸變為綠色,0.75到1這一段是 綠色漸變為藍色; 62 * @param tile 填充模式? 63 * 詳解: 64 * CLAMP : 重復最后一種顏色直到View結束(當你的起始結束的坐標並沒有覆蓋整個View,那么這種模式將會用最后一種顏色填充剩余的部分) 65 * REPEAT: 當你的起始結束的坐標並沒有覆蓋整個View,這種模式將會進行顏色的重新漸變; 66 * MIRROR: 鏡像模式繪制,當你的起始結束的坐標並沒有覆蓋整個View,剩余的部分將會盡量和已經繪制的部分顏色對稱; 67 */ 68 LinearGradient backGradient = null; 69 if (mode == 0) { 70 backGradient = new LinearGradient(0, 0, 0, height / 2, 71 new int[]{colorStart, color1, colorEnd}, new float[]{0, 0.75f, 1f}, Shader.TileMode.CLAMP); 72 } else if (mode == 1) { 73 backGradient = new LinearGradient(0, 0, 0, height / 2, 74 new int[]{colorStart, color1, colorEnd}, new float[]{0, 0.75f, 1f}, Shader.TileMode.REPEAT); 75 } else if (mode == 2) { 76 backGradient = new LinearGradient(0, 0, 0, height / 2, 77 new int[]{colorStart, color1, colorEnd}, new float[]{0, 0.75f, 1f}, Shader.TileMode.MIRROR); 78 } 79 80 81 paint.setShader(backGradient); 82 canvas.drawRect(0, 0, width, height, paint); 83 84 } 85 86 87 }
其他文件:res/values/attr.xml
<resources>
<declare-styleable name="GradientDemoView">
<attr name="mode" format="integer" />
</declare-styleable>
</resources>
res/values/dimens.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<dimen name="shape_width">30dp</dimen>
</resources>
使用此控件的xml:
<GridLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:columnCount="2"
android:rowCount="2">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:gravity="center"
android:orientation="horizontal">
<com.example.colorstudy.GradientDemoView
android:layout_width="@dimen/shape_width"
android:layout_height="@dimen/shape_width"
app:mode="0" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="30dp"
android:text="CLAMP模式" />
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:gravity="center"
android:orientation="horizontal">
<com.example.colorstudy.GradientDemoView
android:layout_width="@dimen/shape_width"
android:layout_height="@dimen/shape_width"
app:mode="1" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="30dp"
android:text="REPEAT模式" />
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:gravity="center"
android:orientation="horizontal">
<com.example.colorstudy.GradientDemoView
android:layout_width="@dimen/shape_width"
android:layout_height="@dimen/shape_width"
app:mode="2" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="30dp"
android:text="MIRROR模式 " />
</LinearLayout>
</GridLayout>
實際效果:

優點:幾乎能夠滿足你能想到的所有漸變需求,處理起來很靈活;漸變色可以是3個以上,每種顏色占比多少可以自己調節,漸變的模式自己指定;而且還可以順帶加上其他特效,就這一點,xml寫配置就無法比擬;
缺點:如果是較為復雜的漸變,對開發人員要求就比較高了,而且還 可能涉及到什么數學算法之類的,數學渣一臉淚有木有·····
ok就醬紫咯。喜歡的大佬,歡迎復制;
