Android LinearGradient的使用

概述

Android自定义view绘制颜色的时候,可以通过setShader可以让view绘制多彩渐变的效果。Android sdk中提供了五个Shader子类供开发者使用,分别是:LinearGradient线性渐变 SweetGradient角度渐变 RadialGradient辐射渐变 BitmapShader图片shader和ComposeShader组合着色器。本文将结合例子对线性渐变做一个介绍。

LinearGradient 线性渐变

构造函数参数说明

 public LinearGradient(float x0, float y0, float x1, float y1,
            @ColorInt int color0, @ColorInt int color1,
            @NonNull TileMode tile)

该构造函数前四个参数代码颜色渐变的起点(x0,y0)和结束点(x1,y1)参数color0与color1代表startColor和endColor。TitleModel 有三个值(CLAMP、MIRROR、REPEAT)代表渐变模式。
列子代码:

 public LinearGradient(float x0, float y0, float x1, float y1, @NonNull @ColorInt int colors[],
            @Nullable float positions[], @NonNull TileMode tile)

该构造函数前四个参数代码颜色渐变的起点(x0,y0)和结束点(x1,y1)参数colors数组代表渐变过度颜色,positions数组代表各过度色的起点位置(浮点类型)。TitleModel 有三个值(CLAMP、MIRROR、REPEAT)代表渐变模式。

例子代码

package com.xol.widget;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.Shader;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.View;

import com.xol.util.CommonUtil;

/**
 * Created by wwzhang on 2019/3/14
 */
public class LinearGradientView extends View {
    private Paint mPaint;
    private LinearGradient mLinearGradient;

    private int mWidthNum = 3;
    private int mHeightNum = 3;
    private int[] colorThree;
    private int[] colorTwo;
    private int mSpace;
    private float mWidth = 0;
    private float mRectRadius = 5;
    private String mContentText = "非淡泊无以明智,非宁静无以致远";


    public LinearGradientView(Context context) {
        super(context);
    }

    public LinearGradientView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    public LinearGradientView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    {
        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mPaint.setStyle(Paint.Style.FILL);
        mPaint.setTextSize(CommonUtil.sp2px(16, getContext()));
        mRectRadius = CommonUtil.dp2px(mRectRadius, getContext());
        colorThree = new int[]{
                Color.parseColor("#ff0000"),
                Color.parseColor("#00ff00"),
                Color.parseColor("#0000ff")};
        colorTwo = new int[]{Color.parseColor("#ff0000"),
                Color.parseColor("#0000ff")};
        mSpace = (int) CommonUtil.dp2px(2, getContext());
        mPaint.setColor(Color.parseColor("#AAAAAA"));
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

    }


    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        drawLinearRound(canvas);

    }

    public void drawLinearRound(Canvas canvas) {
        //绘制两色渐变
        int rectHeight = (int) CommonUtil.dp2px(20, getContext());
        int space = 10;
        //水平clamp
        mLinearGradient = new LinearGradient(0, 0, getMeasuredWidth() / 2,
                0, colorTwo[0], colorTwo[1], Shader.TileMode.CLAMP);
        mPaint.setShader(mLinearGradient);
        canvas.drawRect(0, 0 + space, getMeasuredWidth(), rectHeight + space, mPaint);
        // 水平mirror
        mLinearGradient = new LinearGradient(0, 0, getMeasuredWidth() / 2,
                0, colorTwo[0], colorTwo[1], Shader.TileMode.MIRROR);
        mPaint.setShader(mLinearGradient);
        canvas.drawRect(0, rectHeight + space * 2, getMeasuredWidth(),
                (rectHeight << 1) + space * 2, mPaint);
        //水平repeat
        mLinearGradient = new LinearGradient(0, 0, getMeasuredWidth() / 2,
                0, colorTwo[0], colorTwo[1], Shader.TileMode.REPEAT);
        mPaint.setShader(mLinearGradient);
        canvas.drawRect(0, (rectHeight << 1) + space * 3, getMeasuredWidth(),
                (rectHeight << 1) + rectHeight + space * 3, mPaint);
        //对角线mirror渐变
        mLinearGradient = new LinearGradient(0, 0, 20, 20,
                colorTwo[0], colorTwo[1], Shader.TileMode.MIRROR);
        mPaint.setShader(mLinearGradient);
        canvas.drawRect(0, (rectHeight << 1) + rectHeight + space * 4, getMeasuredWidth(),
                (rectHeight << 2) + space * 4, mPaint);

        //计算
        if (mWidth < 5) {
            mWidth = (getMeasuredWidth() - (mWidthNum + 1) * mSpace) / mWidthNum;
            mHeightNum = (int) (getMeasuredHeight() - CommonUtil.dp2px(120, getContext()) / mWidth);
        }
        //绘制三色渐变
        int count = 0;
        RectF rectF = new RectF();
        for (int i = 0; i < mHeightNum; i++) {
            rectF.top = i * mWidth + (i + 1) * mSpace + (int) CommonUtil.dp2px(120, getContext());
            rectF.bottom = rectF.top + mWidth;
            for (int j = 0; j < mWidthNum; j++) {
                rectF.left = j * mWidth + (j + 1) * mSpace;
                rectF.right = rectF.left + mWidth;
                count++;
                if (count > 9) {
                    break;
                }
                switch (count) {
                    case 1:
                        mLinearGradient = new LinearGradient(rectF.left, rectF.top,
                                rectF.left + (rectF.right - rectF.left) / 2, rectF.top + (rectF.bottom - rectF.top) / 2, colorThree,
                                new float[]{0.0f, 0.66f, 1.0f}, Shader.TileMode.REPEAT);
                        mPaint.setShader(mLinearGradient);
                        break;
                    case 2:
                        mLinearGradient = new LinearGradient(rectF.left, rectF.top,
                                rectF.left + (rectF.right - rectF.left) / 2, rectF.top + (rectF.bottom - rectF.top) / 2, colorThree,
                                new float[]{0.0f, 0.66f, 1.0f}, Shader.TileMode.MIRROR);
                        mPaint.setShader(mLinearGradient);
                        break;
                    case 3:
                        mLinearGradient = new LinearGradient(rectF.left, rectF.top,
                                rectF.left + (rectF.right - rectF.left) / 2, rectF.top + (rectF.bottom - rectF.top) / 2, colorThree,
                                new float[]{0.0f, 0.66f, 1.0f}, Shader.TileMode.CLAMP);
                        mPaint.setShader(mLinearGradient);
                        break;
                    case 4:
                        mLinearGradient = new LinearGradient(rectF.left, rectF.top,
                                rectF.left + (rectF.right - rectF.left) / 2, rectF.top, colorThree,
                                new float[]{0.0f, 0.66f, 1.0f}, Shader.TileMode.REPEAT);
                        mPaint.setShader(mLinearGradient);
                        break;
                    case 5:
                        mLinearGradient = new LinearGradient(rectF.left, rectF.top,
                                rectF.left + (rectF.right - rectF.left) / 2, rectF.top, colorThree,
                                new float[]{0.0f, 0.66f, 1.0f}, Shader.TileMode.MIRROR);
                        mPaint.setShader(mLinearGradient);
                        break;
                    case 6:
                        mLinearGradient = new LinearGradient(rectF.left, rectF.top,
                                rectF.left + (rectF.right - rectF.left) / 2, rectF.top, colorThree,
                                new float[]{0.0f, 0.66f, 1.0f}, Shader.TileMode.CLAMP);
                        mPaint.setShader(mLinearGradient);
                        break;
                    case 7:
                        mLinearGradient = new LinearGradient(rectF.left, rectF.top,
                                rectF.right, rectF.bottom, colorThree,
                                new float[]{0.0f, 0.66f, 1.0f}, Shader.TileMode.REPEAT);
                        mPaint.setShader(mLinearGradient);
                        break;
                    case 8:
                        mLinearGradient = new LinearGradient(rectF.left, rectF.bottom,
                                rectF.right, rectF.bottom, colorThree,
                                new float[]{0.0f, 0.66f, 1.0f}, Shader.TileMode.REPEAT);
                        mPaint.setShader(mLinearGradient);
                        break;
                    case 9:
                        mLinearGradient = new LinearGradient(rectF.left, rectF.bottom,
                                rectF.right, rectF.bottom, colorThree,
                                new float[]{0.5f, 0.75f, 1.0f}, Shader.TileMode.REPEAT);
                        mPaint.setShader(mLinearGradient);
                        break;
                    default:
                        break;
                }
                canvas.drawRoundRect(rectF, mRectRadius, mRectRadius, mPaint);

            }
        }
    }
}

布局文件引入

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.xol.widget.LinearGradientView
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</FrameLayout>

运行结果:

线性渐变文字效果实现

闪动的文字

实现原理,通过matrix水平移动线性shader开始的位置,达到文字闪动的效果

歌词逐字变色效果

实现原理,通过设置线性shader的变色位置,实现文字的逐渐变色。
示例代码:

package com.xol.widget;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.Shader;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.View;

import com.xol.util.CommonUtil;

/**
 * Created by wwzhang on 2019/3/18
 */
public class LinearGradientTextView extends View implements Runnable {

    private Paint mPaint;
    private Matrix mMatrix;
    private String mText;
    private LinearGradient mLinearGradient;
    private long mDuration = 50;
    private int mTransX = 0;
    private Rect rect = new Rect();
    private LinearGradient mKrcLinearGradient;
    private float[] mfKrc = new float[2];
    private String mSingText;
    private Paint mSingPaint;


    public LinearGradientTextView(Context context) {
        super(context);
    }

    public LinearGradientTextView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    public LinearGradientTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    {
        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mSingPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mMatrix = new Matrix();
        mText = "疏疏晴雨弄斜阳,凭栏久,墙外杏花香";
        mSingText = "很爱很爱你所以愿意,不牵绊你";
        mPaint.setTextSize(CommonUtil.dp2px(16, getContext()));
        mSingPaint.setTextSize(CommonUtil.dp2px(16, getContext()));

    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if (null == mLinearGradient) {
            mLinearGradient = new LinearGradient(0, 0, 200, 0,
                    new int[]{Color.parseColor("#440000"),
                            Color.parseColor("#ffffff"),
                            Color.parseColor("#440000")},
                    new float[]{0.0f, 0.5f, 1.0f}, Shader.TileMode.CLAMP);
            mLinearGradient.setLocalMatrix(mMatrix);
            mPaint.setShader(mLinearGradient);
            mfKrc[0] = 0.0f;
            mfKrc[1] = 0.0f;
            mKrcLinearGradient = new LinearGradient(0, 0, getMeasuredWidth(), 0, new int[]{
                    Color.parseColor("#ff0000"),
                    Color.parseColor("#ffffff")},
                    mfKrc,
                    Shader.TileMode.CLAMP);
            mSingPaint.setShader(mKrcLinearGradient);
            postDelayed(this, mDuration);
        }
        mPaint.getTextBounds(mText, 0, mText.length(), rect);
        canvas.drawText(mText, 0, rect.bottom - rect.top, mPaint);
        canvas.drawText(mSingText, 0, getMeasuredHeight() / 2, mSingPaint);
    }

    @Override
    public void run() {
        mTransX += 10;
        if (mTransX > rect.right - rect.left) {
            mTransX = -10;
        }
        mfKrc[0] += 0.01f;
        mfKrc[1] = mfKrc[0];
        if (mfKrc[0] > 1.0f) {
            mfKrc[0] = 0.0f;
            mfKrc[1] = 0.0f;
        }
        mKrcLinearGradient = new LinearGradient(0, 0, getMeasuredWidth(), 0, new int[]{
                Color.parseColor("#ff0000"),
                Color.parseColor("#ffffff")},
                mfKrc,
                Shader.TileMode.CLAMP);
        mSingPaint.setShader(mKrcLinearGradient);
        mMatrix.setTranslate(mTransX, 0);
        mLinearGradient.setLocalMatrix(mMatrix);
        invalidate();
        postDelayed(this, mDuration);

    }
}

布局文件

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    

    <com.xol.widget.LinearGradientTextView
        android:background="#888888"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</FrameLayout>

代码运行效果

在这里插入图片描述
希望对您有所帮助!

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
封面 1 序 2 捐助说明 5 目 录 7 第一章 View的绘图流程 12 1.1、概述 12 1.2、Activity的组成结构 13 1.3、View树的绘图流程 15 1.3.1 测量组件大小 16 1.3.2 确定子组件的位置 17 1.3.3 绘制组件 18 1.4、说点别的 22 1.5 练习作业 22 第二章 Graphics2D API 23 2.1、概述 23 2.2、Point类和PointF类 23 2.3、Rect类和RectF类 25 2.4、Bitmap类和BitmapDrawable类 32 2.5、Canvas类与Paint类 34 2.5.1 绘图概述 34 2.5.2 Paint类 34 2.5.3 Canvas类 39 2.6 练习作业 63 第三章 使用Graphics2D实现动态效果 64 3.1 概述 64 3.2 invalidate()方法 65 3.3 坐标转换 69 3.4 剪切区(Clip) 73 3.5 案例:指针走动的手表 82 3.6 练习作业 88 第四章 双缓存技术 89 4.1 双缓存 89 4.2 在屏幕上绘制曲线 90 4.3 在屏幕上绘制矩形 99 4.4 案例:绘图App 104 4.4.1 绘图属性 106 4.4.2 软件参数 108 4.4.3 绘图缓冲区 109 4.4.4 撤消操作 111 4.4.5 图形绘制 113 4.4.6 绘图区 118 4.4.7 主界面 119 4.5 练习作业 122 第五章 阴影、渐变和位图运算 123 5.1 概述 123 5.2 阴影 123 5.3 渐变 125 5.3.1 线性渐变LinearGradient) 126 5.3.2 径向渐变(RadialGradient) 130 5.3.3 扫描渐变(SweepGradient) 135 5.3.4 位图渐变(BitmapShader) 138 5.3.5 混合渐变(ComposeShader) 140 5.3.6 渐变与Matrix 142 5.4 位图运算 143 5.4.1 PorterDuffXfermode 143 5.4.2 图层(Layer) 146 5.4.3 位图运算技巧 148 5.5 案例1:圆形头像 152 5.6 案例2:刮刮乐 156 5.7 练习作业 161 第六章 自定义组件 163 6.1 概述 163 6.2 自定义组件的基本结构 164 6.3 重写onMeasure方法 166 6.4 组件属性 175 6.4.1 属性的基本定义 175 6.4.2 读取来自style和theme中的属性 181 6.5 案例1:圆形ImageView组件 186 6.6 案例2:验证码组件CodeView 190 6.7 练习作业 202 第七章 自定义容器 204 7.1 概述 204 7.2 ViewGroup类 205 7.2.1 ViewGroup常用方法 205 7.2.2 ViewGroup的工作原理 208 7.2.3 重写onLayout()方法 213 7.3 CornerLayout布局 217 7.3.1 基本实现 217 7.3.2 内边距padding 224 7.3.3 外边距margin 228 7.3.4 自定义LayoutParams 238 7.4 案例:流式布局(FlowLayout) 246 7.5 练习作业 256 第八章 Scroller与平滑滚动 257 8.1 概述 257 8.2 认识scrollTo()和scrollBy()方法 258 8.3 Scroller类 264 8.4 平滑滚动的工作原理 271 8.5 案例:触摸滑屏 272 8.5.1 触摸滑屏的技术分析 272 8.5.2 速度跟踪器VelocityTracker 273 8.5.3 触摸滑屏的分步实现 274 8.6 练习作业 285 第九章 侧边栏 287 9.1 概述 287 9.2 使用二进制保存标识数据 289 9.2.1 位运算符 289 9.2.2 位运算的常用功能 292 9.3 继承自ViewGroup的侧边栏 293 9.4 继承自HorizontalScrollView的侧边栏 304 9.5 练习作业 312 第十章 加强版ListView 313 10.1 概述 313 10.2 ListView的基本使用 314 10.3 ListItem随手指左右滑动 318 10.4 向右滑动删除ListItem 326 10.5 滑动ListItem出现删除按钮 336 10.5.1 列表项专用容器ExtendLayout 337 10.5.2 列表项能滑出删除按钮的ListView 342 10.5.3 定义布局文件 350 10.5.4 显示ListView 351 10.6练习作业 353 案例代码说明 354

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值