自定义控件之跑步圆环

/**
* @author ex-chenmengjia001
* @date 2018/11/26
* 1.画外圆弧
* 2.画内圆弧
* 3.画文字
* 4.进度属性动画
*/
public class QQRunView extends View {

private int mMeasuredWidth;
private int mMeasuredHeight;
private Paint mPaint = new Paint();
private int mRountColor = Color.BLUE;
//圆弧宽度
private int mRoundWidth = 38;
//圆弧进度颜色
private int mProgressColor = Color.RED;
private int mProgressStep = 50;
private int mMaxStep = 100;
private float numberTextSize = 30;
//步数
private String stepNumber = "50";
private int mCenterY;
//当前圆弧长度
private float currentAngleLength = 0;

public QQRunView(Context context) {
this(context, null);
}

public QQRunView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}

public QQRunView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int Widthmode = MeasureSpec.getMode(widthMeasureSpec);
int heightmode = MeasureSpec.getMode(heightMeasureSpec);
mMeasuredWidth = getMeasuredWidth();
mMeasuredHeight = getMeasuredHeight();
//宽度是wrap_content
if (Widthmode == MeasureSpec.AT_MOST) {
mMeasuredWidth = 600;
widthMeasureSpec= MeasureSpec.makeMeasureSpec(mMeasuredWidth, MeasureSpec.AT_MOST);

}
//高度是wrap_content
if (heightmode == MeasureSpec.AT_MOST) {
mMeasuredHeight = 600;
heightMeasureSpec=MeasureSpec.makeMeasureSpec(mMeasuredHeight, MeasureSpec.AT_MOST);

}

super.onMeasure(widthMeasureSpec, heightMeasureSpec);

}

@Override
protected void onDraw(Canvas canvas) {
//计算中心点
int centerX = mMeasuredWidth / 2;
mCenterY = mMeasuredHeight / 2;
mPaint.setStrokeWidth(mRoundWidth);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setColor(mRountColor);
mPaint.setStyle(Paint.Style.STROKE);
//半径
int radius = centerX - mRoundWidth;
RectF oval = new RectF(centerX - radius, mCenterY - radius, centerX + radius, mCenterY + radius);
//起始角度
float startAngle = 135;
//结束角度
float sweepAngle = 270;
//画外圆弧
canvas.drawArc(oval, startAngle, sweepAngle, false, mPaint);
//画进度圆弧
drawArcProgress(canvas, oval, startAngle, currentAngleLength);
//画数字
drawTextNumber(canvas, centerX);
//画文字
drawTextStepString(canvas, centerX);


}

/**
* 画文字步数
* @param canvas
* @param centerX
*/
private void drawTextStepString(Canvas canvas, int centerX) {
Paint paint = new Paint();
paint.setTextSize(dipToPx(18));
paint.setTextAlign(Paint.Align.CENTER);
paint.setAntiAlias(true);
paint.setColor(getResources().getColor(R.color.colorPrimaryDark));
String stepString = "步数";
Rect rect = new Rect();
paint.getTextBounds(stepString, 0, stepString.length(), rect);
canvas.drawText(stepString, centerX, mCenterY + rect.height() + getFontHeight(dipToPx(26)), paint);

}

public int getFontHeight(float fontSize) {
Paint paint = new Paint();
paint.setTextSize(fontSize);
Rect bounds_Number = new Rect();
paint.getTextBounds(stepNumber, 0, stepNumber.length(), bounds_Number);
return bounds_Number.height();
}

/**
* 画数字
* @param canvas
* @param centerX
*/
private void drawTextNumber(Canvas canvas, int centerX) {
Paint paint = new Paint();
paint.setTextAlign(Paint.Align.CENTER);
paint.setAntiAlias(true);
paint.setTextSize(dipToPx(26));
Typeface typeface = Typeface.create(Typeface.SANS_SERIF, Typeface.NORMAL);
paint.setTypeface(typeface);
Rect rect = new Rect();
paint.getTextBounds(stepNumber, 0, stepNumber.length(), rect);
canvas.drawText(stepNumber, centerX, mCenterY + rect.height() / 2, paint);
}

/**
* 画进度圆弧
* @param canvas
* @param oval
* @param startAngle
* @param sweepAngle
*/
private void drawArcProgress(Canvas canvas, RectF oval, float startAngle, float sweepAngle) {
Paint paint = new Paint();
paint.setStrokeJoin(Paint.Join.ROUND);
paint.setStrokeCap(Paint.Cap.ROUND);
paint.setStyle(Paint.Style.STROKE);
paint.setAntiAlias(true);
paint.setStrokeWidth(mRoundWidth);
paint.setColor(mProgressColor);
canvas.drawArc(oval, startAngle, sweepAngle, false, paint);
}

/**
* 开启圆弧动画
* @param start
* @param current
* @param length
*/
private void setAnimation(float start, float current, int length) {
ValueAnimator valueAnimator = ValueAnimator.ofFloat(start, current);
valueAnimator.setDuration(length);
valueAnimator.setTarget(currentAngleLength);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
currentAngleLength = (float) animation.getAnimatedValue();
invalidate();
}
});
valueAnimator.start();
}

/**
* 设置步数
* @param totalStep
* @param currCount
*/
public void setCurrentCount(int totalStep, int currCount) {
stepNumber = currCount + "";
setTextSize(currCount);
if (currCount >= totalStep) {
currCount = totalStep;
}
float percent = (float) (currCount * 1.0 / totalStep);
float sweepAngel = percent * 270;
setAnimation(0, sweepAngel, 3000);

}

public void setTextSize(int num) {
String s = String.valueOf(num);
int length = s.length();
if (length <= 4) {
numberTextSize = dipToPx(50);
} else if (length > 4 && length <= 6) {
numberTextSize = dipToPx(40);
} else if (length > 6 && length <= 8) {
numberTextSize = dipToPx(30);
} else if (length > 8) {
numberTextSize = dipToPx(25);
}
}

private int dipToPx(float dip) {
float density = getContext().getResources().getDisplayMetrics().density;
return (int) (dip * density + 0.5f * (dip >= 0 ? 1 : -1));
}


}

 

 

 

猜你喜欢

转载自blog.csdn.net/qq_34015596/article/details/85230541