Android View — Gradient 漸變

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)

  1. float x0, float y0, float x1, float y1 定義了起始點的和結束點的坐標。
  2. int[] colors 顏色數組,在線性方向上漸變的顏色。
  3. float[] positions 和上邊的數組對應,取值[0..1],表示每種顏色的在線性方向上所占的百分比。可以為Null,為Null 是均勻分布。
  4. Shader.TileMode tile 表示繪制完成,還有剩余空間的話的繪制模式。

第二種 構造函數是第一種的簡化版,只支持兩種顏色。

LinearGradient(float x0, float y0, float x1, float y1, int color0, int color1, Shader.TileMode tile)
  1. float x0, float y0, float x1, float y1 定義了起始點的和結束點的坐標。
  2. int color0, int color1, 開始顏色和結束的顏色
  3. 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);
        }
gradient_linear.png

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
            );
        }

gradient_radial.png

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
            );
        }
gradient_sweep.png

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
            );
linear_tilemode.png

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
            );                        
radial_tilemode.png

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>
DrawableLinearGradientView.png
<?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>
DrawableRadialGradientView.png
<?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>
DrawableSweepGradientView.png
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容