一个仪表盘自定义控件

mac2024-03-31  36

 最近开发中设计给出了一个类似于仪表盘的控件,虽然可以用多张图代替,但是还是写了一个类似的自定义控件,成果如下图:

1、首先把原点设置在圆心

//把方框平移到正中间 canvas.translate(dx, dy); canvas.save(); canvasR = Math.min(getWidth(), getHeight()) / 2; markWidth = canvasR / 20; tableWidth = canvasR / 10; mPaint.setStyle(Paint.Style.STROKE);

2、从外围开始描绘控件

//填写文字刻度 mPaint.setTextSize(outTextSize); int count = 0; while (count < mMaxCount) { //填写外围文字 Rect bounds = new Rect(); String text = 100 / (mMaxCount - 1) * count + ""; mPaint.getTextBounds(text, 0, text.length(), bounds); float offSet = (bounds.bottom - bounds.top); //角度 float angle = startAngle + sweepAngle / (mMaxCount - 1) * count; textWidth = offSet + 3;//3间距显得好看点 //半径 float r = canvasR - textWidth; canvas.rotate(90 + angle, getmX(r, angle), getmY(r, angle)); canvas.drawText(text, getmX(r, angle), getmY(r, angle), mPaint); canvas.rotate(-90 - angle, getmX(r, angle), getmY(r, angle)); //填写大刻度 canvas.drawLine(getmX(r - 3, angle), getmY(r - 3, angle), getmX(r - markWidth, angle), getmY(r - markWidth, angle), mPaint); int count0 = 1; //填写小刻度 while (count > 0 && count0 < mMinCount) { //角度 float angle0 = angle - sweepAngle / (mMaxCount - 1) + sweepAngle / (mMaxCount - 1) * count0 / mMinCount; canvas.drawLine(getmX(r - markWidth / 2, angle0), getmY(r - markWidth / 2, angle0), getmX(r - markWidth, angle0), getmY(r - markWidth, angle0), mPaint); count0++; } count++; } //刻度下面弧线 float markR = canvasR - textWidth - markWidth; RectF markRectf = new RectF(-markR, -markR, markR, markR); mPaint.setStyle(Paint.Style.STROKE); canvas.drawArc(markRectf, startAngle, sweepAngle, false, mPaint); float tableR = markR - canvasR / 40 - tableWidth / 2; RectF mTableRectF = new RectF(-tableR, -tableR, tableR, tableR); //进度条底部 Path tablePath = new Path(); tablePath.addArc(mTableRectF, startAngle - 90, sweepAngle); //计算路径的长度 PathMeasure pathMeasure = new PathMeasure(tablePath, false); float length = pathMeasure.getLength(); float step = length / 21; DashPathEffect dashPathEffect = new DashPathEffect(new float[]{step * 9 / 10, step / 10}, 0); mPaint.setPathEffect(dashPathEffect); mPaint.setStrokeWidth(tableWidth); canvas.rotate(90); canvas.drawPath(tablePath, mPaint); canvas.rotate(-90); //进度条 Path progressPath = new Path(); progressPath.addArc(mTableRectF, startAngle - 90, sweepAngle * progress / 100); SweepGradient mColorShader = new SweepGradient(0, 0, SWEEP_GRADIENT_COLORS, null); mPaint.setShader(mColorShader); canvas.rotate(90); canvas.drawPath(progressPath, mPaint); canvas.rotate(-90); //画带阴影的圆 float circleR = tableR - canvasR / 40 - tableWidth / 2; initPaint(); canvas.drawCircle(-canvasR / 160, canvasR / 160, circleR, mPaint); mPaint.setColor(Color.WHITE); canvas.drawCircle(0, 0, circleR, mPaint); mPaint.setColor(Color.parseColor("#cccccc")); mPaint.setStyle(Paint.Style.STROKE); canvas.drawCircle(0, 0, circleR, mPaint); //画内圆 mPaint.setStyle(Paint.Style.FILL); mPaint.setColor(Color.parseColor("#fafafa")); canvas.drawCircle(0, 0, circleR * 2 / 5, mPaint); mPaint.setStyle(Paint.Style.STROKE); mPaint.setColor(Color.parseColor("#dddddd")); canvas.drawCircle(0, 0, circleR * 2 / 5, mPaint); //画进度小圆点 mPaint.setColor(Color.parseColor("#FF6610")); mPaint.setStyle(Paint.Style.FILL); canvas.drawCircle(getmX(circleR - canvasR / 20, startAngle + sweepAngle * progress / 100) , getmY(circleR - canvasR / 20, startAngle + sweepAngle * progress / 100), canvasR / 40, mPaint); //画中间字符 Rect bounds = new Rect(); String text = progress + "%"; mPaint.setTextSize(proTextSize); mPaint.getTextBounds(text, 0, text.length(), bounds); float offSet = (bounds.bottom - bounds.top); Rect bounds2 = new Rect(); String text2 = decText; mPaint.setTextSize(decTextSize); mPaint.setColor(Color.parseColor("#cccccc")); mPaint.getTextBounds(text, 0, text.length(), bounds2); float offSet2 = (bounds2.bottom - bounds2.top); canvas.drawText(text2, 0, (offSet2 + offSet + 3) / 2, mPaint); mPaint.setColor(Color.parseColor("#FF6610")); mPaint.setTextSize(proTextSize); canvas.drawText(text, 0, (offSet2 + offSet + 3) / 2 - offSet2 - 3, mPaint);

求x,y坐标方法

private float getmX(float r, float angle) { return (float) Math.cos(angle * Math.PI / 180) * r; } private float getmY(float r, float angle) { return (float) Math.sin(angle * Math.PI / 180) * r; }

源码:https://download.csdn.net/download/qq_40667603/11945307

 

最新回复(0)