如下图所示是产品设计出来的自定义view,风险等级的;其中的一部分就是中间的那个渐变的bar;这里就讲解下LinearGradient
整个自定义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的构造方法和各个参数的含义
/** 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:**
未完待续