线性渐变LinearGradient的使用

如下图所示是产品设计出来的自定义view,风险等级的;其中的一部分就是中间的那个渐变的bar;这里就讲解下LinearGradient

线性渐变LinearGradient的使用_第1张图片

整个自定义view可以拆分成几部分:
绘制:
- 中间的条形bar
- 上下的刻度线和刻度值
- 下面的圆圈
- 滑块
- 左下角和右下角的文字(整个可以忽略)
事件:
- 滑块的滚动
- 刻度值的放大
- 滑块的矫正(只能滑到刻度值上,其他地方做判断,离哪个近就跳到哪一个)

这节主要来将中间的条形bar的渐变色
首先我把中间的条目定义出来

package com.newtouch.levelbar;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.drawable.BitmapDrawable;
import android.util.AttributeSet;
import android.view.ViewGroup;

/**
 * 功能:自定义的风险等级
 * @author xiehj
 * @time 2016/12/22 14:06
 */
public class LevelBar extends ViewGroup {

    private int mViewWidth = 0;//view的宽度
    private int mViewHeight = 0;//view的高度
    private int leftAndRightMargin = 10;//左右两边的间距,可以用户自定义
    private int mLevelBarHeight = 30;//等级条的高度

    //创建一个画笔
    private Paint mPaint = new Paint();

    //初始化画笔
    private void initPaint() {
        mPaint.setColor(Color.BLACK);       //设置画笔颜色
        mPaint.setStyle(Paint.Style.FILL);  //设置画笔模式为填充
        mPaint.setStrokeWidth(10f);         //设置画笔宽度为10px
    }

    public LevelBar(Context context) {
        this(context, null);
    }

    public LevelBar(Context context, AttributeSet attrs) {
        super(context, attrs);

        setBackgroundDrawable(new BitmapDrawable());

        /**
         * 获得我们所定义的自定义样式属性
         */
        TypedArray a = context.obtainStyledAttributes(attrs,R.styleable.LevelBar);
        leftAndRightMargin = a.getDimensionPixelSize(R.styleable.LevelBar_leftAndRightMargin,10);//左右间距
        mLevelBarHeight = a.getDimensionPixelSize(R.styleable.LevelBar_barHeight,30);//bar高度

        a.recycle();
        initPaint();
    }

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

        //默认测量模式为EXACTLY,否则请使用上面的方法并指定默认的宽度和高度
        mViewWidth = MeasureSpec.getSize(widthMeasureSpec);
        mViewHeight = MeasureSpec.getSize(heightMeasureSpec);
        setMeasuredDimension(mViewWidth, mViewHeight);
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        //设置滑块在父布局的位置
    }

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

        drawRiskLevelBar(canvas);//画条形bar
    }

    /**
     * 画风险等级条
     * @param canvas
     */
    private void drawRiskLevelBar(Canvas canvas) {

        //渐变色
        LinearGradient linearGradient = new LinearGradient(0, 0, getMeasuredWidth(), 0,new int[]{getResources().getColor(R.color.start),getResources().getColor(R.color.end)}, null, LinearGradient.TileMode.CLAMP);
        mPaint.setShader(linearGradient);

        //矩形左上角和右下角的点的坐标
        RectF rectF = new RectF(leftAndRightMargin,mViewHeight/2-mLevelBarHeight/2,mViewWidth-leftAndRightMargin,mViewHeight/2+mLevelBarHeight/2);
        canvas.drawRoundRect(rectF, 4, 4, mPaint);
    }

}

效果图:
线性渐变LinearGradient的使用_第2张图片

首先看下LinearGradient的构造方法和各个参数的含义
线性渐变LinearGradient的使用_第3张图片

/** Create a shader that draws a linear gradient along a line.
        @param x0           The x-coordinate for the start of the gradient line
        @param y0           The y-coordinate for the start of the gradient line
        @param x1           The x-coordinate for the end of the gradient line
        @param y1           The y-coordinate for the end of the gradient line
        @param  colors      The colors to be distributed along the gradient line
        @param  positions   May be null. The relative positions [0..1] of
                            each corresponding color in the colors array. If this is null,
                            the the colors are distributed evenly along the gradient line.
        @param  tile        The Shader tiling mode
    */
    public LinearGradient(float x0, float y0, float x1, float y1, int colors[], float positions[],
            TileMode tile) {
        if (colors.length < 2) {
            throw new IllegalArgumentException("needs >= 2 number of colors");
        }
        if (positions != null && colors.length != positions.length) {
            throw new IllegalArgumentException("color and position arrays must be of equal length");
        }
        mType = TYPE_COLORS_AND_POSITIONS;
        mX0 = x0;
        mY0 = y0;
        mX1 = x1;
        mY1 = y1;
        mColors = colors;
        mPositions = positions;
        mTileMode = tile;
        init(nativeCreate1(x0, y0, x1, y1, colors, positions, tile.nativeInt));
    }

    /** Create a shader that draws a linear gradient along a line.
        @param x0       The x-coordinate for the start of the gradient line
        @param y0       The y-coordinate for the start of the gradient line
        @param x1       The x-coordinate for the end of the gradient line
        @param y1       The y-coordinate for the end of the gradient line
        @param  color0  The color at the start of the gradient line.
        @param  color1  The color at the end of the gradient line.
        @param  tile    The Shader tiling mode
    */
    public LinearGradient(float x0, float y0, float x1, float y1, int color0, int color1,
            TileMode tile) {
        mType = TYPE_COLOR_START_AND_COLOR_END;
        mX0 = x0;
        mY0 = y0;
        mX1 = x1;
        mY1 = y1;
        mColor0 = color0;
        mColor1 = color1;
        mTileMode = tile;
        init(nativeCreate2(x0, y0, x1, y1, color0, color1, tile.nativeInt));
    }

构造方法一参数:

x0表示渲染起始位置的x坐标
y0表示渲染起始位置的y坐标
x1表示渲染结束位置的x坐标
y1表示渲染结束位置的y坐标
colors[]表示渲染的颜色,它是一个颜色数组,数组长度必须大于等于2
positions[]表示colors数组中几个颜色的相对位置,是一个float类型的 数组,该数组的长度必须与colors数组的长度相同。如果这个参数使用null也可以,这时系统会按照梯度线来均匀分配colors数组中的颜色
tile表示平铺方式,有三种,我们分别来看

构造方法二参数:

x0表示渲染起始位置的x坐标
y0表示渲染起始位置的y坐标
x1表示渲染结束位置的x坐标
y1表示渲染结束位置的y坐标
color1表示渲染的第一个颜色
color1表示渲染的第二个颜色
tile表示平铺方式,有三种,我们分别来看

上面的效果可以使用两种中的任意一种

 LinearGradient linearGradient = new LinearGradient(0, 0, getMeasuredWidth(), 0,new int[]{getResources().getColor(R.color.start),getResources().getColor(R.color.end)}, null, LinearGradient.TileMode.CLAMP);
        LinearGradient linearGradient = new LinearGradient(0, 0, getMeasuredWidth(), 0,getResources().getColor(R.color.start),getResources().getColor(R.color.end), LinearGradient.TileMode.CLAMP);

到这里前面几个参数都没有问题了,下面来看下最后一个TitleMode的模式

public enum TileMode {
        /**
         * replicate the edge color if the shader draws outside of its
         * original bounds
         */
        CLAMP   (0),
        /**
         * repeat the shader's image horizontally and vertically
         */
        REPEAT  (1),
        /**
         * repeat the shader's image horizontally and vertically, alternating
         * mirror images so that adjacent images always seam
         */
        MIRROR  (2);

        TileMode(int nativeInt) {
            this.nativeInt = nativeInt;
        }
        final int nativeInt;
    }

可以看到它是枚举类型的,并且有三种
LinearGradient.TileMode.CLAMP:**
LinearGradient.TileMode.REPEAT:**
LinearGradient.TileMode.MIRROR:**

未完待续

你可能感兴趣的:(android)