package com.example.arcapplication;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PathMeasure;
import android.graphics.Point;
import android.graphics.PointF;
import android.graphics.Rect;
import android.graphics.RectF;
import android.text.TextPaint;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import androidx.annotation.Nullable;
public class ArcView extends View {
private Paint mPaint;
private TextPaint mTextPaint;
private Bitmap mBitmap;
private Path mPath;
private PathMeasure mPathMeasure;
private float mLength;
private float[] pos;
private float[] tan;
public ArcView(Context context) {
this(context, null);
}
public ArcView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public ArcView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeWidth(12);
mTextPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
mTextPaint.setStrokeCap(Paint.Cap.ROUND);
mTextPaint.setStyle(Paint.Style.STROKE);
mTextPaint.setTextSize(26);
mTextPaint.setColor(Color.BLACK);
mBitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.ic_battery2);
mRect = new RectF();
mRect.set((float) (getWidth() / 2f - mRadius), (float) (getHeight() / 2f - mRadius),
(float) (getWidth() / 2f + mRadius), (float) (getHeight() / 2f + mRadius));
mOuterRect = new RectF();
mOuterRect.set((float) (getWidth() / 2f - mOuterRadius), (float) (getHeight() / 2f - mOuterRadius),
(float) (getWidth() / 2f + mOuterRadius), (float) (getHeight() / 2f + mOuterRadius));
float top = mTextPaint.getFontMetrics().top;
float bottom = mTextPaint.getFontMetrics().bottom;
float offsetV = ((itemWidth) / 2) - bottom;
mOuterIconRect = new RectF();
mOuterIconRect.set(mOuterRect.left - offsetV ,mOuterRect.top - offsetV ,
mOuterRect.right + offsetV ,mOuterRect.bottom + offsetV);
baseLine =
(mTextPaint.getFontMetrics().descent
- mTextPaint.getFontMetrics().ascent) / 2 - mTextPaint.getFontMetrics().descent;
mPath = new Path();
mPathMeasure = new PathMeasure();
}
float baseLine;
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.translate(getWidth() / 2f, getHeight() / 2f);
mPaint.setColor(Color.BLUE);
canvas.drawArc(mRect, 0, 360, false, mPaint);
mPaint.setColor(Color.RED);
canvas.drawArc(mOuterRect, 0, 360, false, mPaint);
drawUp(canvas, 180 + 90 - 56);
drawUp(canvas, 180 + 90 - 24);
drawUp(canvas, 180 + 90 + 6);
drawDown(canvas, 180 - 90 + 56);
drawDown(canvas, 180 - 90 + 24);
drawDown(canvas, 180 - 90 - 6);
}
private void drawUp(Canvas canvas, int degrees){
mPath.reset();
mPath.addArc(mOuterIconRect, 0, 360);
mPathMeasure.setPath(mPath, false);
mLength = mPathMeasure.getLength();
pos = new float[2];
tan = new float[2];
canvas.save();
mPathMeasure.getPosTan(mLength * (degrees / 360f), pos, tan);
canvas.rotate(degrees, pos[0], pos[1]);mPaint.setColor(Color.RED);
RectF rectF = new RectF(pos[0] - itemWidth/2, pos[1] - itemWidth/2,
pos[0] + itemWidth/2, pos[1] + itemWidth/2);
canvas.drawRect(rectF, mPaint);
canvas.restore();
// 角度弧度互换
// Math.toDegrees(angrad); //角度转换成弧度,返回:angrad * 180d / PI
// Math.toRadians(angdeg); //弧度转换成角度,返回:angdeg / 180d * PI
mPath.reset();
mPath.addArc(mOuterRect.left, mOuterRect.top,mOuterRect.right, mOuterRect.bottom,
degrees, 18);
canvas.drawTextOnPath("100%", mPath, 15,0f, mTextPaint);
PointF point = drawArcIcon(250, degrees);
mPaint.setColor(Color.RED);
canvas.drawPoint(point.x, point.y, mPaint);
}
private void drawDown(Canvas canvas, int degrees){
mPath.reset();
mPath.addArc(mOuterIconRect, 0, 360);
mPathMeasure.setPath(mPath, false);
mLength = mPathMeasure.getLength();
pos = new float[2];
tan = new float[2];
canvas.save();
mPathMeasure.getPosTan(mLength * (degrees / 360f), pos, tan);
canvas.rotate(degrees, pos[0], pos[1]);mPaint.setColor(Color.RED);
RectF rectF = new RectF(pos[0] - itemWidth/2, pos[1] - itemWidth/2,
pos[0] + itemWidth/2, pos[1] + itemWidth/2);
canvas.drawRect(rectF, mPaint);
canvas.restore();
// 角度弧度互换
// Math.toDegrees(angrad); //角度转换成弧度,返回:angrad * 180d / PI
// Math.toRadians(angdeg); //弧度转换成角度,返回:angdeg / 180d * PI
mPath.reset();
mPath.addArc(mOuterRect.left, mOuterRect.top,mOuterRect.right, mOuterRect.bottom,
degrees, -18);
canvas.drawTextOnPath("100%", mPath, 15, Math.abs(mTextPaint.getFontMetrics().top)-baseLine, mTextPaint);
PointF point = drawArcIcon(250, degrees);
mPaint.setColor(Color.RED);
canvas.drawPoint(point.x, point.y, mPaint);
}
private final RectF mRect;
private final RectF mOuterRect;
private final RectF mOuterIconRect;
private float mRadius = 216;
private float mOuterRadius = 250;
private float itemWidth = 30;
private PointF drawArcIcon(float radius, float startAngle) {
// 计算,中心点到menu item中心的距离
float x = (float) (Math.cos(Math.toRadians(startAngle)) * radius);
float y = (float) (Math.sin(Math.toRadians(startAngle)) * radius);
Log.d("wyj", "x : " + x + ", y : " + y);
return new PointF(x, y);
}
}