先给大家上效果图
看上去还不错对吧
其实实现起来也很简单的,整理一下要用到的知识点:
自定义View画椭圆drawOval
画圆弧drawArc
画圆drawCircle
画文字drawText
给大家上代码、然后是一些需要注意的点
- 重写自定义View的三个
构造方法
public FlexProgressView(Context context) {
this(context, null);
}
public FlexProgressView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public FlexProgressView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
一般应该都是这么写的,就是不管使用哪几种创建view的方式,最后都会调到init()方法中去
- 然后是
init()
方法,去初始化一下画笔,进度条宽度,颜色什么的,当然也不会写死这些东西,后面都暴露方法出去,可以让
private void init() {
max = 100;
mStrokeWidth = 10;
mProgressWidth = 30;
mTextSize = 30 ;
// 边框
mStrokePaint = new Paint();
mStrokePaint.setColor(Color.RED);
mStrokePaint.setStyle(Paint.Style.STROKE);
mStrokePaint.setAntiAlias(true);
mStrokePaint.setStrokeWidth(mStrokeWidth);
// 进度条
mProPaint = new Paint();
mProPaint.setColor(Color.BLUE);
mProPaint.setStyle(Paint.Style.STROKE);
mProPaint.setAntiAlias(true);
mProPaint.setStrokeWidth(mProgressWidth);
// 两边的小球
cPaint = new Paint();
cPaint.setColor(Color.BLUE);
cPaint.setStyle(Paint.Style.FILL);
cPaint.setAntiAlias(true);
// 写文字
mTextPaint = new Paint();
mTextPaint.setColor(Color.BLUE);
mTextPaint.setStyle(Paint.Style.STROKE);
mTextPaint.setAntiAlias(true);
mTextPaint.setTextSize(mTextSize);
// 给一个默认的进度值
setProgress(30);
}
- 然后重写父类的
onMeasure
方法,让这个控件变成正方形的
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
mWidth = MeasureSpec.getSize(widthMeasureSpec);
// mHeight = MeasureSpec.getSize(heightMeasureSpec);
mHeight = mWidth;
setMeasuredDimension(mWidth, mWidth);
}
- 然后重写父类的
onDraw
方法,在画布上画我们需要背景线、进度条、文字、还有进度条两端的小球
@Override
protected void onDraw(Canvas canvas) {
// 如果进度条细一些的话、就应该显示在边框的中间,反之边框应该显示在进度条的中间
float stWidth = mProgressWidth > mStrokeWidth ? mProgressWidth : mStrokeWidth;
RectF oval = new RectF(); //RectF对象
oval.left = stWidth / 2; //左边
oval.top = stWidth / 2; //上边
oval.right = mWidth - (stWidth / 2); //右边
oval.bottom = mHeight - (stWidth / 2); //下边
// 画边框
canvas.drawOval(oval, mStrokePaint);
// 画进度
canvas.drawArc(oval, startAngle, sweepAngle, false, mProPaint);
// 画左边的小球
float radius = (mWidth / 2) - (stWidth / 2);
float centerX = mWidth / 2;
float centerY = mHeight / 2;
double aa = startAngle * Math.PI / 180;
float x1 = (float) (centerX + (radius) * Math.cos(aa));
float y1 = (float) (centerY + (radius) * Math.sin(aa));
canvas.drawCircle(x1, y1, mProgressWidth / 2, cPaint);
// 画右边的小球
float f = (270 - startAngle + 270);
if (f >= 360) f = f - 360;
aa = f * Math.PI / 180;
x1 = (float) (centerX + (radius) * Math.cos(aa));
y1 = (float) (centerY + (radius) * Math.sin(aa));
canvas.drawCircle(x1, y1, mProgressWidth / 2, cPaint);
// 画文字
if (mVisibility == View.VISIBLE){ // 对外暴露控制方法,是否显示
Paint.FontMetricsInt fontMetrics = mTextPaint.getFontMetricsInt();
int baseline = (int) ((oval.bottom + oval.top - fontMetrics.bottom - fontMetrics.top) / 2);
mTextPaint.setTextAlign(Paint.Align.CENTER);
int pro = (int) progress;
canvas.drawText(pro+"", oval.centerX(), baseline, mTextPaint);
}
}
这里需要注意的几个地方就是drawArc还有画进度条的端的小球,如果不画两端的小球进度条会比较难看,感兴趣的可以注释代码去试试就知道了。觉得很难理解的可以去看看 。画圆弧、写文字等
- 然后是对外暴露的控制方法了,可以去设置一些画笔的大小啊,颜色啊之类的
/**
* 设置进度
* @param progressWidth
*/
public void setProgress(float progress) {
if (progress < 0) {
progress = 0;
} else if (progress > max) {
progress = max;
}
this.progress = progress;
startAngle = 270 - (float) (this.progress / max * 180.0);
sweepAngle = (270 - startAngle) * 2;
postInvalidate();
}
/**
* 设置边框颜色
* @param color
*/
public void setStrokeColor(int color) {
mStrokePaint.setColor(color);
invalidate();
}
/**
* 设置进度条颜色
* @param color
*/
public void setProgressColor(int color) {
mProPaint.setColor(color);
invalidate();
}
/**
* 设置边框宽度
* @param width
*/
public void setStrokeWidth(float width) {
mStrokeWidth = width;
mStrokePaint.setStrokeWidth(width);
invalidate();
}
/**
* 设置进度条的宽度
* @param progressWidth
*/
public void setProgressWidth(float progressWidth) {
mProgressWidth = progressWidth;
mProPaint.setStrokeWidth(mProgressWidth);
invalidate();
}
/**
* 设置 文字大小
* @param textSize
*/
public void setTextSize(int textSize) {
mTextSize = textSize;
mTextPaint.setTextSize(mTextSize);
invalidate();
}
/**
* 设置 文字颜色
*/
public void setTextColor(int textColor) {
mTextPaint.setColor(textColor);
invalidate();
}
/**
* 设置文字是否可见
* @param visibility View.VISIBLE 可见
*/
public void setTextVisibility(int visibility){
if (mVisibility != visibility){
mVisibility = visibility;
invalidate();
}
}
最后给大家看一下运行时的样子
给大家放上资源地址吧
转载请注明出处 http://blog.csdn.net/q771410116/article/details/77919760
源码下载