public class DashBoardView extends View { private Context context; // 圆 private Paint mPaint; // 弧 private Paint mPaintArc; // 弧的外接矩形 private RectF rectFArc, rectFArc2; // text private Paint mPaintText; // line private Paint mPaintLine; // 指针路径 private Path path; // 宽、高 private float width, height; private float radius, arcWidth, arcWidth2, arcStrokeWidth, pointerLength, lineLength; // 设置旋转角度 public float degrees = 0; private float paddingLeft, paddingTop, paddingRight, paddingBottom; // 底部描述文字 private String desc; public DashBoardView(Context context) { this(context, null); } public DashBoardView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public DashBoardView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); this.context = context; init(); } private void init() { mPaint = new Paint(); mPaint.setColor(context.getResources().getColor(R.color.zs)); mPaint.setStyle(Paint.Style.FILL); mPaint.setAntiAlias(true); mPaintArc = new Paint(); // 空心 mPaintArc.setStyle(Paint.Style.STROKE); mPaintArc.setAntiAlias(true); mPaintLine = new Paint(); mPaintLine.setColor(context.getResources().getColor(R.color.zs)); mPaintLine.setStyle(Paint.Style.FILL); mPaintLine.setAntiAlias(true); path = new Path(); mPaintText = new Paint(); mPaintText.setColor(context.getResources().getColor(R.color.zs)); mPaintText.setAntiAlias(true); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); int wMode = MeasureSpec.getMode(widthMeasureSpec); int wSize = MeasureSpec.getSize(widthMeasureSpec); int hMode = MeasureSpec.getMode(heightMeasureSpec); int hSize = MeasureSpec.getSize(heightMeasureSpec); // 处理宽高为 wrap_content的情况 if (wMode == MeasureSpec.AT_MOST && hMode == MeasureSpec.AT_MOST) { setMeasuredDimension(200, 200); } else if (wMode == MeasureSpec.AT_MOST) { setMeasuredDimension(200, hSize); } else if (hMode == MeasureSpec.AT_MOST) { setMeasuredDimension(wSize, 200); } // 获取padding paddingLeft = getPaddingLeft(); paddingTop = getPaddingTop(); paddingRight = getPaddingRight(); paddingBottom = getPaddingBottom(); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); this.width = w - paddingLeft - paddingRight; this.height = h - paddingTop - paddingBottom;// 640 850 360-360 // 外圆弧的半径 if (width <= height) { arcWidth = width / 2; } else { arcWidth = height / 2; } // 弧的描边宽度 arcStrokeWidth = (10 / 180f) * arcWidth; // 位于圆心处的圆的半径 radius = 15 / 180f * arcWidth; // 指针的长度 pointerLength = 110 / 180f * arcWidth; // 刻度线的长度 lineLength = 15 / 180f * arcWidth; // 绘制内外弧的画笔 mPaintArc.setStrokeWidth(arcStrokeWidth); // 内圆弧的半径 arcWidth2 = arcWidth - mPaintArc.getStrokeWidth(); // 刻度线描边宽度 mPaintLine.setStrokeWidth(2 / 180f * arcWidth); mPaintText.setTextSize(20 / 180f * arcWidth); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); // 注释以下语句会让中心小圆的圆心位于左上角处 canvas.translate(width / 2 + paddingLeft, height / 2 + paddingTop); canvas.drawCircle(0, 0, radius, mPaint); // 将画布平移后,(0,0)点的位置就挪动到中间小圆的位置了 rectFArc = new RectF(-arcWidth, -arcWidth, arcWidth, arcWidth); rectFArc2 = new RectF(-arcWidth2, -arcWidth2, arcWidth2, arcWidth2); // 绘制外围弧形 mPaintArc.setColor(context.getResources().getColor(R.color.mainTextBlack)); /** * 矩形范围 开始角度 扫过的角度 是否将弧两端和圆心连接 画笔 */ canvas.drawArc(rectFArc, 165, 210, false, mPaintArc); // 绘制内围弧形 mPaintArc.setColor(context.getResources().getColor(R.color.hs)); canvas.drawArc(rectFArc2, 165, 70, false, mPaintArc); mPaintArc.setColor(context.getResources().getColor(R.color.zs)); canvas.drawArc(rectFArc2, 235, 70, false, mPaintArc); mPaintArc.setColor(context.getResources().getColor(R.color.ls)); canvas.drawArc(rectFArc2, 305, 70, false, mPaintArc); // 刻度线的起始位置 (理解-的含义) 从内弧边界一定距离开始 float startXLine = -(arcWidth2 - (1 / 2) * arcStrokeWidth); // 刻度线的终止位置 float stopXLine = -(arcWidth2 - (1 / 2) * arcStrokeWidth - lineLength); // 文本的起始位置 (理解-的含义) 从内弧边界一定距离开始 float startXText = -mPaintText.measureText("中") / 2; // 文本的宽度 float stopXText = -(arcWidth2 - (1 / 2) * mPaintArc.getStrokeWidth() - (2.5f) * lineLength); // 绘制"中"的刻度线 canvas.drawLine(0, startXLine, 0, stopXLine, mPaintLine); mPaintText.setColor(context.getResources().getColor(R.color.zs)); canvas.drawText("中", startXText, stopXText, mPaintText); mPaintLine.setColor(context.getResources().getColor(R.color.hs)); for (int i = 0; i <= 2; i++) { canvas.rotate(-35); if (i == 1) { mPaintText.setColor(context.getResources().getColor(R.color.hs)); canvas.drawText("低", startXText, stopXText, mPaintText); } canvas.drawLine(0, startXLine, 0, stopXLine, mPaintLine); } canvas.rotate(105); mPaintLine.setColor(context.getResources().getColor(R.color.ls)); for (int i = 0; i <= 2; i++) { canvas.rotate(35); if (i == 1) { mPaintText.setColor(context.getResources().getColor(R.color.ls)); canvas.drawText("高", startXText, stopXText, mPaintText); } canvas.drawLine(0, startXLine, 0, stopXLine, mPaintLine); } // 纠正画布,刚好在"中"的位置 canvas.rotate(-105); mPaintText.setColor(context.getResources().getColor(R.color.mainTextBlack)); canvas.drawText(desc, -mPaintText.measureText(desc) / 2, pointerLength, mPaintText); // 画笔坐标系旋转 canvas.rotate(-105 + degrees); // 绘制指针 mPaintLine.setColor(context.getResources().getColor(R.color.zs)); path.moveTo(radius / 2, 0); path.lineTo(0, -pointerLength); path.lineTo(-radius / 2, 0); canvas.drawPath(path, mPaintLine); } /** * 设置旋转角度 */ public void setDegrees(float degrees) { this.degrees = degrees; invalidate(); } /** * 获取旋转角度 */ public float getDegrees() { return this.degrees; } /** * 设置底部描述 */ public void setTextDesc(String desc) { this.desc = desc; invalidate(); } }private void initView() { dashBoardView = (DashBoardView) findViewById(R.id.dashBoardView); // 账户安全 仪表盘 ObjectAnimator animator = ObjectAnimator.ofFloat(dashBoardView,"degrees", 175); animator.setDuration(3000); // 设置插值器 animator.setInterpolator(new DecelerateInterpolator()); animator.start(); dashBoardView.setTextDesc("你的账户等级 高"); }<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="zxxk.ext.dashboardview.MainActivity"> <zxxk.ext.dashboardview.DashBoardView android:id="@+id/dashBoardView" android:layout_width="match_parent" android:layout_height="300dp" android:padding="50dp" /> </RelativeLayout>
刻度表盘源码分析
最新推荐文章于 2024-05-16 10:07:35 发布