Android View — Gradient 漸變
Android 支持三種顏色漸變, LinearGradient(線性漸變) RadialGradient (徑向漸變) SweepGradient(掃描漸變)。這三種漸變繼承自android.graphics.Shader, Paint 類通過setShader支持漸變。
java.lang.Object
android.graphics.Shader
android.graphics.LinearGradient
android.graphics.RadialGradient
android.graphics.SweepGradient
1. LinearGradient
線性漸變就是在線性方向的的漸變。有兩個構造函數,
// Public constructors
LinearGradient(float x0, float y0, float x1, float y1, int[] colors, float[] positions, Shader.TileMode tile)
- float x0, float y0, float x1, float y1 定義了起始點的和結束點的坐標。
- int[] colors 顏色數組,在線性方向上漸變的顏色。
- float[] positions 和上邊的數組對應,取值[0..1],表示每種顏色的在線性方向上所占的百分比。可以為Null,為Null 是均勻分布。
- Shader.TileMode tile 表示繪制完成,還有剩余空間的話的繪制模式。
第二種 構造函數是第一種的簡化版,只支持兩種顏色。
LinearGradient(float x0, float y0, float x1, float y1, int color0, int color1, Shader.TileMode tile)
- float x0, float y0, float x1, float y1 定義了起始點的和結束點的坐標。
- int color0, int color1, 開始顏色和結束的顏色
- Shader.TileMode tile 表示繪制完成,還有剩余空間的話的繪制模式。
@Override
protected void onChildDraw(Canvas canvas) {
LinearGradient linearGradient = new LinearGradient(
0, 0,
mRectF.right, mRectF.top,
Color.RED, Color.YELLOW,
Shader.TileMode.MIRROR
);
mPaint.setShader(linearGradient);
canvas.drawRect(mRectF, mPaint);
}

RadialGradient
RadialGradient 是圓環一樣的的漸變,RadialGradient 同樣是兩個構造函數,
RadialGradient(float centerX, float centerY, float radius, int[] colors, float[] stops, Shader.TileMode tileMode)
1.float centerX, float centerY 漸變的中心點 圓心
2.float radius 漸變的半徑
3.int[] colors 漸變顏色數組
4.float[] stops 和顏色數組對應, 每種顏色在漸變方向上所占的百分比取值[0, 1]
5.Shader.TileMode tileMode 表示繪制完成,還有剩余空間的話的繪制模式。
RadialGradient(float centerX, float centerY, float radius, int centerColor, int edgeColor, Shader.TileMode tileMode)
1.float centerX, float centerY 漸變的中心點 圓心
2.float radius 漸變的半徑
3.int centerColor, int edgeColor 中心點顏色和邊緣顏色
4.Shader.TileMode tileMode 表示繪制完成,還有剩余空間的話的繪制模式
@Override
protected void onChildDraw(Canvas canvas) {
RadialGradient radialGradient = new RadialGradient(
mRectF.centerX(), mRectF.centerY(),
Math.min(mRectF.centerX(), mRectF.centerY()),
new int[]{Color.RED, Color.YELLOW, Color.BLUE}, null,
Shader.TileMode.MIRROR
);
mPaint.setShader(radialGradient);
canvas.drawCircle(
mRectF.centerX(), mRectF.centerY(),
Math.min(mRectF.centerX(), mRectF.centerY()),
mPaint
);
}

SweepGradient
SweepGradient 是和角度有關的漸變。以某一點為圓心,隨著角度的大小發生漸變。
SweepGradient(float cx, float cy, int[] colors, float[] positions)
1.float cx, float cy 中心點坐標
2.int[] colors 顏色數組
3.float[] positions 數組顏色在漸變方向上所占的百分比
SweepGradient(float cx, float cy, int color0, int color1)
1.float cx, float cy 中心點坐標
2.int color0, int color1 開始顏色 結束顏色
@Override
protected void onChildDraw(Canvas canvas) {
SweepGradient sweepGradient = new SweepGradient(
mRectF.centerX(), mRectF.centerY(),
new int[]{Color.RED, Color.YELLOW, Color.BLACK, Color.MAGENTA},
null
);
mPaint.setShader(sweepGradient);
canvas.drawCircle(
mRectF.centerX(), mRectF.centerY(),
Math.min(mRectF.centerX(), mRectF.centerY()),
mPaint
);
}

Shader.TileMode
在LinearGradient RadialGradient 漸變中,構造函數的最后一個參數為 Shader.TileMode 類型,決定了如果View還有剩余空間,如何繪制。
Shader.TileMode | |
---|---|
CLAMP (0) | 邊緣拉伸 replicate the edge color if the shader draws outside of its original bounds |
REPEAT (1) | repeat the shader's image horizontally and vertically |
MIRROR (2) | repeat the shader's image horizontally and vertically, alternating mirror images so that adjacent images always seam |
LinearGradient Shader.TileMode
從上到下依次為:CLAMP REPEAT MIRROR
LinearGradient linearGradient = new LinearGradient(
0, mRectF.centerY(),
mRectF.centerX(), mRectF.centerY(),
Color.RED, Color.YELLOW,
Shader.TileMode.CLAMP
);
LinearGradient linearGradient = new LinearGradient(
0, mRectF.centerY(),
mRectF.centerX(), mRectF.centerY(),
Color.RED, Color.YELLOW,
Shader.TileMode.REPEAT
);
LinearGradient linearGradient = new LinearGradient(
0, mRectF.centerY(),
mRectF.centerX(), mRectF.centerY(),
Color.RED, Color.YELLOW,
Shader.TileMode.MIRROR
);

RadialGradient Shader.TileMode
從上到下依次為:CLAMP REPEAT MIRROR
RadialGradient radialGradient = new RadialGradient(
mRectF.centerX(), mRectF.centerY(),
Math.min(mRectF.centerX(), mRectF.centerY())/2,
new int[]{Color.RED, Color.YELLOW, Color.BLUE}, null,
Shader.TileMode.CLAMP
);
RadialGradient radialGradient = new RadialGradient(
mRectF.centerX(), mRectF.centerY(),
Math.min(mRectF.centerX(), mRectF.centerY())/2,
new int[]{Color.RED, Color.YELLOW, Color.BLUE}, null,
Shader.TileMode.REPEAT
);
RadialGradient radialGradient = new RadialGradient(
mRectF.centerX(), mRectF.centerY(),
Math.min(mRectF.centerX(), mRectF.centerY())/2,
new int[]{Color.RED, Color.YELLOW, Color.BLUE}, null,
Shader.TileMode.MIRROR
);

ShapeDrawable 中的漸變
一些背景的漸變通過定義 Shape Drawable 來實現。Shape Drawable 有gradient 屬性。
type | 類型 linear radial sweep 三種類型 |
---|---|
angle | 起始角度,0 左邊;90 下邊,180,右邊,270 上邊。共8個方向,從0開始每次增加45 |
centerX centerY | 中心點所在的百分比 |
endColor startColor | 開始顏色,結束顏色 |
centerColor | 中心點顏色 |
gradientRadius | 漸變半徑 android:type="radial" 才有作用 |
type | 類型 linear radial sweep 三種類型 |
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<gradient
android:angle="0"
android:centerX="0.5"
android:centerY="0.5"
android:endColor="@color/colorPrimary"
android:startColor="@color/colorAccent"
android:type="linear" />
<corners android:radius="5dip" />
</shape>

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:dither="true"
android:innerRadius="@dimen/pain_canvas_height"
android:shape="oval" >
<gradient
android:angle="0"
android:centerX="0.5"
android:centerY="0.5"
android:endColor="@color/colorPrimary"
android:startColor="@color/colorAccent"
android:type="radial"
android:gradientRadius="@dimen/pain_canvas_height"/>
</shape>

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval" >
<gradient
android:angle="0"
android:centerX="0.5"
android:centerY="0.5"
android:endColor="@color/colorPrimary"
android:startColor="@color/colorAccent"
android:gradientRadius="@dimen/pain_canvas_height"/>
</shape>
