Android View — Gradient 渐变

秦博延
2023-12-01

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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SuxQ2ZvU-1585192275446)(https://github.com/louiewh/ImageHosting/raw/master/gradient/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
            );
        }

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uVf7E2JL-1585192275449)(https://github.com/louiewh/ImageHosting/raw/master/gradient/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
            );
        }

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Y0I7KbDs-1585192275450)(https://github.com/louiewh/ImageHosting/raw/master/gradient/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
            );

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UtNRYIjz-1585192275451)(https://github.com/louiewh/ImageHosting/raw/master/gradient/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
            );                        

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-km5GoKGq-1585192275452)(https://github.com/louiewh/ImageHosting/raw/master/gradient/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>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HaAqSqQR-1585192275453)(https://github.com/louiewh/ImageHosting/raw/master/gradient/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>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FAR9Q2WT-1585192275454)(https://github.com/louiewh/ImageHosting/raw/master/gradient/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>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ee1z9gGH-1585192275455)(https://github.com/louiewh/ImageHosting/raw/master/gradient/DrawableSweepGradientView.png)]

 类似资料: