1 绘图基础简析
2 效果图
3 源码
public class CustomLineProgressView extends View {
//设置默认最大进度
public int max =100;
//设置默认初始化进度
public int progress=0;
//设置View默认的大小
private int mDefaultWidth = dp2px(60);
private int mDefaultPadding = dp2px(10);
// 定义设置进度圆的默认半径
private int mRadius = mDefaultWidth/2;
//圆环的默认宽度
private int mProgressBarHeight = dp2px(5);
//声明初始化一个画笔
private Paint mPaint = new Paint();
//设置未加载进度的默认颜色
private int mUnReachedBarColor = 0xffe6e6e6;
//设置已加载进度的默认颜色
private int mReachedBarColor = 0xff89cc99;
//测量后的实际view的大小
private int mMeasureWidth;
private int mMeasureHeight;
private RectF mRectF;
public CustomLineProgressView(Context context) {
super(context);
//初始化画笔风格,图形参数,如圆圈的颜色,绘制的文字等
initView();
}
public CustomLineProgressView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
setWillNotDraw(false);// 防止onDraw方法不执行
//初始化画笔风格,图形参数,如圆圈的颜色,绘制的文字等
initView();
//获取自定义View中自定义属性的值
TypedArray lTypedArray = context.obtainStyledAttributes(attrs, R.styleable.circularProgress);
//获取定义圆弧进度的颜色
mReachedBarColor=lTypedArray.getColor(R.styleable.circularProgress_progressColor,mReachedBarColor);
mUnReachedBarColor=lTypedArray.getColor(R.styleable.circularProgress_progressBackgroundColor,mUnReachedBarColor);
}
private void initView() {
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setAntiAlias(true);
mPaint.setDither(true);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setTextSize(dp2px(10));
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
Log.e("progress",w + " h " +h+" oldw "+oldw+" oldh "+ oldh);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
//测量计算
mMeasureWidth = measureSize(widthMeasureSpec);
mMeasureHeight = measureSize(heightMeasureSpec);
//重新测量
setMeasuredDimension(mMeasureWidth, mMeasureHeight);
//绘制圆环的半径
mRadius=(mMeasureWidth -mDefaultPadding*2-mProgressBarHeight-getPaddingLeft()-getPaddingRight())/2;
//绘制进度圆弧的外切矩形定义
mRectF = new RectF(-mRadius, -mRadius, mRadius, mRadius);
//动态设置绘制文本的大小
mPaint.setTextSize(dp2px(mRadius/4));
}
private int measureSize(int measureSpec) {
int result = 0;
int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);
if (specMode == MeasureSpec.EXACTLY){
//当specMode = EXACTLY时,精确值模式,即当我们在布局文件中为View指定了具体的大小
result = specSize;
}else {
result = mDefaultWidth; //指定默认大小
if (specMode == MeasureSpec.AT_MOST){
result = Math.min(result,specSize);
}
}
return result;
}
@Override
protected synchronized void onDraw(Canvas canvas) {
//获取显示进度的文字指示
String text = progress + "%";
//获取显示进度的文字的宽与高
float textWidth = mPaint.measureText(text);
float textHeight = (mPaint.descent() + mPaint.ascent()) / 2;
canvas.save();
//将画布移动到中心 view中心为原点(0,0)
canvas.translate(mMeasureWidth/2,mMeasureHeight/2);
mPaint.setStyle(Paint.Style.STROKE);
//绘制未加载的进度,也就是绘制环背景
mPaint.setColor(mUnReachedBarColor);
mPaint.setStrokeWidth(mProgressBarHeight);
//点(0,0)为原心
canvas.drawCircle(0, 0, mRadius, mPaint);
//绘制已加载的圆环进度
mPaint.setColor(mReachedBarColor);
mPaint.setStrokeWidth(mProgressBarHeight);
//计算进度圆弧角度
float sweepAngle = progress * 1.0f / max * 360;
//绘制圆弧进度
canvas.drawArc(mRectF, 0,
sweepAngle, false, mPaint);
//绘制显示进行的颜色
mPaint.setStyle(Paint.Style.FILL);
//绘制显示文本
canvas.drawText(text, - textWidth / 2, - textHeight,
mPaint);
canvas.restore();
}
//将设置的db转为屏幕像素
protected int dp2px(int dpVal) {
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
dpVal, getResources().getDisplayMetrics());
}
//设置最大进度
public void setMax(int i) {
if (i<0||i>100){
i=100;
}
max=i;
}
//更新进度
public void setProgress(int number) {
if (number>100){
number=100;
}
if (number<0){
number=0;
}
progress=number;
invalidate();
}
/**
* 设置进度已加载进度条的颜色
* 这里只写了这个设置颜色
* 当然也可以写出代码动态设置改变 未加载进度条的颜色
* 还有显示文字的颜色
* 还有进度条的宽度等等
* @param color
*/
public void setReachedBarColor(int color){
this.mReachedBarColor = color;
}
本文同步分享在 博客“早起的年轻人”(CSDN)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。