/**
* 饼状图百分比控件
*/
public class PercentCircle extends View {
private final String tag = "PercentCircle";
/**
* 绘制百分比的圆,一共有两部分,分别是内圆、外圆;
* 思路:首先需要两支画笔, 设置画笔对应的属性等;
*/
/**
* 内部圆画笔
*/
private Paint mBackgroundInPaint;
/**
* 内部圆背景颜色
*/
private int mBackgroundInColor;
/**
* 圆心的坐标
*/
private int mCircleX;
private int mCircleY;
/**
* 当前角度
*/
private float mCurrentAngle;
/**
* 圆的外接矩形
*/
private RectF mArcRectF;
/**
* 开始绘制的角度
*/
private float mStartSweepValue;
/**
* 要绘制的角度
*/
private float mTargetPercent;
/**
* 外边圆的画笔
*/
private Paint mRingPaint;
/**
* 外层圆半径
*/
private int mRadius;
/**
* 外层圆颜色
*/
private int mRingColor;
private float newPercent;
public PercentCircle(Context context) {
super(context);
init(context);
}
public PercentCircle(Context context, AttributeSet attrs) {
super(context, attrs);
LogUtils.v(tag, "percentCircle:" + "PercentCircle(Context context, AttributeSet attrs)");
mRadius = 360;
// 背景圆的颜色
mBackgroundInColor = Color.WHITE;
// 外圆环的颜色
mRingColor = Color.parseColor("#a1e0fd");
init(context);
}
public PercentCircle(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
LogUtils.v(tag, "percentCircle:" + "PercentCircle(Context context, AttributeSet attrs, int defStyleAttr)");
init(context);
}
private void init(Context context) {
//圆环开始角度 -90° 正北方向
mStartSweepValue = -90;
//当前角度
mCurrentAngle = 0;
//设置中心园的画笔
mBackgroundInPaint = new Paint();
mBackgroundInPaint.setAntiAlias(true);
mBackgroundInPaint.setColor(mBackgroundInColor);
mBackgroundInPaint.setStyle(Paint.Style.FILL);
//设置外圆环的画笔
mRingPaint = new Paint();
mRingPaint.setAntiAlias(true);
mRingPaint.setColor(mRingColor);
mRingPaint.setStyle(Paint.Style.FILL);
}
// 主要是测量wrap_content时候的宽和高,因为宽高一样,只需要测量一次宽即可,高等于宽
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(measure(widthMeasureSpec), measure(widthMeasureSpec));
}
// 当wrap_content的时候,view的大小根据半径大小改变,但最大不会超过屏幕
private int measure(int measureSpec) {
int result = 0;
//1、先获取测量模式 和 测量大小
//2、如果测量模式是MatchParent 或者精确值,则宽为测量的宽
//3、如果测量模式是WrapContent ,则宽为 直径值 与 测量宽中的较小值;否则当直径大于测量宽时,会绘制到屏幕之外;
int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);
if (specMode == MeasureSpec.EXACTLY) {
result = specSize;
} else {
result = (mRadius * 2);
if (specMode == MeasureSpec.AT_MOST) {
result = Math.min(result, specSize);
}
}
return result;
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
//1、如果半径大于圆心的横坐标,需要手动缩小半径的值,否则画到屏幕之外;
//4、画背景圆的外接矩形,用来画圆环;
mCircleX = getMeasuredWidth() / 2;
mCircleY = getMeasuredHeight() / 2;
if (mRadius > mCircleX) {
mRadius = mCircleX;
}
mArcRectF = new RectF(mCircleX - mRadius, mCircleY - mRadius, mCircleX + mRadius, mCircleY + mRadius);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//1、先画外边大的圆
//1、再画中间的小圆覆盖大圆的中间部分
mRingColor = Color.parseColor("#a1e0fd");
mRingPaint.setColor(mRingColor);
canvas.drawArc(mArcRectF, mStartSweepValue, (float) (3.6 * mTargetPercent), true, mRingPaint);
mRingColor = Color.parseColor("#f99740");
mRingPaint.setColor(mRingColor);
canvas.drawArc(mArcRectF, (float) (mStartSweepValue + 3.6 * mTargetPercent), (float) (3.6 * newPercent), true, mRingPaint);
canvas.drawCircle(mCircleX, mCircleY, mRadius * 0.672f, mBackgroundInPaint);
}
public void setTargetPercent(float targetPercent) {
mTargetPercent = targetPercent;
}
public void setNewPercent(float newPercent) {
this.newPercent = newPercent;
}
}