最近在研究一些自定义绘制控件,不可避免的会用到Paint,gradient,
先贴代码:
public class ProgressView1 extends View {
private Paint mOutPaint;
private Paint mInPaint;
private Paint mRecPaint;
private Paint mNumPaint;
private Paint mBgPaint;
private RectF mCurRectF;
private RectF mOutRectF;
private int mWidth;
private int mHeight;
private int mRecRadio;
private int circleRadio;
private int mPadding;
/**
* 进度条最大值
*/
private float maxCount;
/**
* 进度条当前值
*/
private float currentCount;
private String mMaxStr;
private String mCurStr;
private int mMaxRadiums;
private static final int[] SECTION_COLORS = {0xFF19DE8E, 0xFF19DE8E, 0xFF21CAE0};
private float mCurSize;
public ProgressView1(Context context) {
this(context, null);
}
public ProgressView1(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public ProgressView1(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
mWidth = getMeasuredWidth();
mHeight = getMeasuredHeight();
mPadding = mHeight / 6;//padding值
mRecRadio = mHeight / 2 - mPadding;//进度条宽度
mMaxRadiums = mHeight / 2;//圆的高度
}
private void init() {
//外圆
mOutPaint = new Paint();
mOutPaint.setStyle(Paint.Style.STROKE);
// 消除锯齿
mOutPaint.setAntiAlias(true);
// 设置画笔的颜色
mOutPaint.setColor(SECTION_COLORS[0]);
// 设置paint的外框宽度
mOutPaint.setStrokeWidth(UIUtils.dp2px(5));
// 白色实体圆
mInPaint = new Paint();
// 消除锯齿
mInPaint.setAntiAlias(true);
// 设置画笔的颜色
mInPaint.setColor(Color.WHITE);
//进度条画笔
mRecPaint = new Paint();
// 消除锯齿
mRecPaint.setAntiAlias(true);
// 设置画笔的颜色
mRecPaint.setColor(SECTION_COLORS[0]);
//数字画笔
mNumPaint = new Paint();
// 消除锯齿
mNumPaint.setAntiAlias(true);
// 设置画笔的颜色
mNumPaint.setColor(SECTION_COLORS[0]);
mNumPaint.setTextSize(UIUtils.dp2px(14));
//
mBgPaint = new Paint();
// 消除锯齿
mBgPaint.setAntiAlias(true);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
mCurStr = String.valueOf((int) currentCount);
mCurSize = mNumPaint.measureText(mCurStr);
if (currentCount != maxCount) {
drawMaxView(canvas);
}
drawCurruntView(canvas);
}
private void drawCurruntView(Canvas canvas) {
float section = currentCount / maxCount;
if (section <= 1.0f / 3.0f) {
if (section != 0.0f) {
mRecPaint.setColor(SECTION_COLORS[0]);
mOutPaint.setColor(SECTION_COLORS[0]);
} else {
mRecPaint.setColor(Color.TRANSPARENT);
mOutPaint.setColor(Color.TRANSPARENT);
}
} else {
int count = (section <= 1.0f / 3.0f * 2) ? 2 : 3;
int[] colors = new int[count];
System.arraycopy(SECTION_COLORS, 0, colors, 0, count);
float[] positions = new float[count];//这个position数值只创建不使用,是无效的
if (count == 2) {
positions[0] = 0.0f;
// positions[1] = 1.0f - positions[0];
positions[1] = 1.0f;
} else {
positions[0] = 0.0f;
positions[1] = (maxCount / 3) / currentCount;
// positions[2] = 1.0f - positions[0] * 2;
positions[2] = 1.0f;
}
positions[positions.length - 1] = 1.0f;//这一句跟上面两句是
LinearGradient shader = new LinearGradient(3, 3, (mWidth - 3) * section, /mHeight - /3,
colors, null, Shader.TileMode.MIRROR);
mRecPaint.setShader(shader);
mOutPaint.setShader(shader);
}
if (section == 0) {
//绘制进度条中的空心圆
mOutPaint.setColor(SECTION_COLORS[0]);
canvas.drawCircle(mPadding + mRecRadio, mHeight / 2,
mMaxRadiums - mOutPaint.getStrokeWidth() / 2, mOutPaint);
mInPaint.setColor(Color.WHITE);
// //画实体圆
canvas.drawCircle(mPadding + mRecRadio, mHeight / 2,
mRecRadio, mInPaint);
//
// //画当前的文字
mNumPaint.setColor(SECTION_COLORS[0]);
canvas.drawText(mCurStr, mPadding + mRecRadio - mCurSize / 2
, mHeight / 2 + mCurSize / 2, mNumPaint);//绘制文字这里确定绘制文字的坐下角坐标
} else {
mCurRectF = new RectF(mPadding, mPadding, mWidth * section - mPadding, mHeight - mPadding);//正确的右边距是(mWidth-2*padding)*selection+padding,但实际上这细小的差距是无法肉眼识别的
canvas.drawRoundRect(mCurRectF, mRecRadio, mRecRadio, mRecPaint);
// canvas.drawCircle(mWidth * section - mPadding - mRecRadio, mHeight / 2,
// mMaxRadiums - mOutPaint.getStrokeWidth() / 2, mOutPaint);
//绘制外圈
canvas.drawCircle(mPadding + (mWidth - 2 * mPadding) * section - mRecRadio, mHeight / 2, mMaxRadiums - mOutPaint.getStrokeWidth() / 2, mOutPaint);
mInPaint.setColor(Color.WHITE);
//
// //画实体圆
// canvas.drawCircle(mWidth * section - mPadding - mRecRadio, mHeight / 2,
// mRecRadio, mInPaint);
canvas.drawCircle(mPadding + (mWidth - 2 * mPadding) * section - mRecRadio, mHeight / 2,
mRecRadio, mInPaint);
//
// //画当前的文字
mNumPaint.setColor(SECTION_COLORS[0]);
canvas.drawText(mCurStr, mWidth * section - mRecRadio - mPadding - mCurSize / 2
, mHeight / 2 + mCurSize / 2, mNumPaint);
}
// }
}
private void drawMaxView(Canvas canvas) {
//绘制圆角矩形
mBgPaint.setColor(0xFFDDE0E4);
mOutRectF = new RectF(mPadding, mPadding, mWidth - mPadding, mHeight - mPadding);
canvas.drawRoundRect(mOutRectF, mRecRadio, mRecRadio, mBgPaint);
//绘制末尾的圆形
mInPaint.setColor(0xFFDDE0E4);
canvas.drawCircle(mWidth - mPadding - mMaxRadiums, mHeight / 2, mMaxRadiums, mInPaint);
//绘制进度末尾的总进度数值
mNumPaint.setColor(0xFF9AA3B3);
Typeface font = Typeface.create(Typeface.SANS_SERIF, Typeface.BOLD);
mNumPaint.setTypeface(font);
mMaxStr = String.valueOf((int) maxCount);
canvas.drawText(mMaxStr, mWidth - mMaxRadiums - mPadding - mCurSize / 2, mHeight / 2 +
mCurSize / 2, mNumPaint);
}
public void setMaxCount(float maxCount) {
this.maxCount = maxCount;
}
/***
* 设置当前的进度值
*
* @param currentCount
*/
public void setCurrentCount(float currentCount) {
this.currentCount = currentCount > maxCount ? maxCount : currentCount;
invalidate();
}
}
1.首先,在控件的onMeasure方法中
mWidth = getMeasuredWidth();
mHeight = getMeasuredHeight();
获取到控件的宽高然后根据宽高设置控件的padding圆的半径等等,简而言之就是,初始化控件的尺寸信息
2.第二步,drawMaxView()方法绘进度条总得长度
3.第三步,drawCurruntView()方法,绘制当前进度,这里用到了
LinearGradient shader = new LinearGradient(3, 3, (mWidth - 3) * section, /mHeight - /3,
colors, null, Shader.TileMode.MIRROR);
渐变渲染的一个对象,设置了这个对象开始渲染和结束渲染的位置,通过这个对象达到进度条颜色渐变的效果