
需求: 根据的服务端返回 百分比进行旋转。在旋转结束后展示当前点的百分比。并且在0~50% 标签在右边 50%~100% 在左边。根据进度不同需要绘制两个不同的颜色
需要熟悉的Api view 绘制流程 Canvas paint Matrix ,简单数学计算 已知圆心半径 弧度求圆上任意点(x,y) 坐标。
最主要是一种解决问题思路和 不怕麻烦。
主要修改 HoloCircularProgressBar 类中 mesure() 和 ondraw()下面贴出来核心代码:
@Override
protected void onDraw(final Canvas canvas) {
canvas.translate(mTranslationOffsetX, mTranslationOffsetY);
final float progressRotation = getCurrentRotation();
if (progress < MAX_END_FLOAT_VALUE) {
canvas.drawArc(mCircleBounds, 0, 360, false, mBackgroundColorPaint);
}
if (!mOverrdraw) {
} else {
canvas.drawArc(mCircleBounds, 270, progressRotation, false, mProgressColorPaint);
//canvas.drawArc(mCircleBounds, 270, progressRotation - 360, false, mProgressColorPaint); 两周
}
if (isCircleEnabled()) {
canvas.save();
// rotate the square by 45 degrees
canvas.rotate(progressRotation - 90);
// canvas.rotate(45, mCirclePosX, mCirclePosY);
mSquareRect.left = mCirclePosX - mCircleRadius / 3;
mSquareRect.right = mCirclePosX + mCircleRadius / 3;
mSquareRect.top = mCirclePosY - mCircleRadius / 3;
mSquareRect.bottom = mCirclePosY + mCircleRadius / 3;
float x = mSquareRect.left + (mSquareRect.right - mSquareRect.left) / 2;
float y = mSquareRect.top + (mSquareRect.bottom - mSquareRect.top) / 2;
canvas.drawCircle(x, y, getResources().getDimensionPixelSize(R.dimen.circle_7), mThumbColorPaint);
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setColor(getResources().getColor(R.color.text_white));
canvas.drawCircle(x, y, getResources().getDimensionPixelSize(R.dimen.circle_6), paint);
canvas.restore();
这里修改了 原来的ondraw() 绘制圆环的方式。实现起来更容易理解,
canvas.drawArc(mCircleBounds, 0, 360, false, mBackgroundColorPaint);
画圆环
canvas.drawArc(mCircleBounds, 270, progressRotation, false, mProgressColorPaint);
画外层圆环,至于为什么从270 度 开始。以为 270度正好从圆环顶部开始画。
接下来画小圆和小圆上的白点。 根据算好的偏移量。就好了
主要的代码
/**
* 画标签
*
* @param canvas
* @param x
* @param y
* @param paint 画笔
*/
private void drawTag(Canvas canvas, float x, float y, Paint paint) {
canvas.rotate(270);
//计算小圆半径 进行回调
double x2 = mRadius * Math.cos(getProgress() * Math.PI * 2);
double y2 = mRadius * Math.sin(getProgress() * Math.PI * 2);
Matrix matrix = new Matrix();
if ((progress > 0.5f && progress <= 1f)) {
matrix.setTranslate((float) x2 + getResources().getDimension(R.dimen.width_f1), (float) y2);
TextView rightView = (TextView) View.inflate(MyApp.getInstance().getApplicationContext(), R.layout.view_right_progress_tag, null);
rightView.setText(endPercent + "%");
matrix.postRotate(90, (float) x2 + getResources().getDimension(R.dimen.width_25), (float) y2 - getResources().getDimension(R.dimen.width_14));
canvas.drawBitmap(convertViewToBitmap(rightView), matrix, paint);
} else {
matrix.setTranslate((float) (20f + x2), (float) y2);
TextView leftView = (TextView) View.inflate(MyApp.getInstance().getApplicationContext(), R.layout.view_left_progress_tag, null);
leftView.setText(endPercent + "%");
matrix.postRotate(90, (float) x2, (float) y2);
canvas.drawBitmap(convertViewToBitmap(leftView), matrix, paint);
}
canvas.restore();
LogUtil.d(TAG, "小圆圆心坐标" + " (" + x2 + "," + y2 + ")" +
"大圆圆心坐标 = (" + mTranslationOffsetX + "," + mTranslationOffsetY + ")" + "大圆半径=" + mRadius + "旋转角度=" + getCurrentRotation());
}
首先旋转画布。根据数学公式计算出圆环上的圆心点(x1,y1)准备画标签。
Eg:只是这个标签费和好长时间,一直没有想出好的方式,最后使用matrix 解决了。让标签绕着小圆的圆心旋转。和偏移。之前一直绕着大圆旋转。造成标签不能水平放置,会有一个旋转角度。
标签是左右两边各一个,为什么? 方便setText()。否则标签里面的百分比会有旋转。这里需要一个工具类: view 转 bitmap 的方法
/**
* view 转换为 bitmap
*
* @param view
* @return
*/
public static Bitmap convertViewToBitmap(View view) {
view.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED), View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());
view.buildDrawingCache();
Bitmap bitmap = view.getDrawingCache();
return bitmap;
}
参考: