效果图:
我写的这篇博客个人感觉非常的不详细,这也是根据UI设计的,不过大家掌握下文所点出来的重点方法也可以将其绘制出来,这里就不详细介绍绘制流程了
UI分析:
这个UI细分为表盘刻度、进度条底色、进度条渐变色、最外层那个实心圆球和文字描述。接下来就逐个实现
一、绘制表盘刻度
1、绘制表盘的刻度主要是用了画布的旋转来进行绘制
利用canvas.rotate()方法来旋转画布。利用canva.drawText()方法绘制文字,最后canvas.restore()释放画布让其回到原来的位置
/**
* 旋转画布画刻度
* @param canvas 画布
*/
private void paintPercentText(Canvas canvas){
paint.setTextSize(percentTextSize);
paint.setColor(pinkColor);
paint.setStrokeWidth(1);
paint.setTextAlign(Paint.Align.CENTER);
for (int i=0;i<=10;i++){
//保存画布
canvas.save();
//旋转角度,第一个参数是旋转的角度、第二个参数和第三个参数是旋转中心点x和y
canvas.rotate((float) (spaceAngle * i + -135 + spaceAngle), width / 2, radius);
//画文字
canvas.drawText(i * 10 + "", width / 2, outerArcWidth + insideArcWidth + spaceWidth * 2, paint);
canvas.restore();
}
}
二、绘制进度条底色
绘制进度条的底色主要用paint.setStrokeCap(Paint.Cap.ROUND)将画笔设置为圆角和canvas.drawArc()方法,这里就需要计算好矩形框以及起始的角度和结束的角度
/**画两条线的底色*/
private void paintPercentBack(Canvas canvas){
paint.setColor(grayColor);
paint.setStrokeWidth(outerArcWidth);//outerArcWidth
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeCap(Paint.Cap.ROUND);//设置为圆角
paint.setAntiAlias(true);
//绘制最外层圆条底色
outerArcRadius=radius-outerArcWidth;
outerArea= new RectF(width/2 - outerArcRadius, radius - outerArcRadius, width/2 + outerArcRadius, radius + outerArcRadius);
canvas.drawArc(outerArea,
(float) (180 - floatAngel),
(float) (180 + 2 * floatAngel), false, paint);
//绘制里层大宽度弧形
paint.setColor(pinkColor);
paint.setStrokeWidth(insideArcWidth);
paint.setStyle(Paint.Style.STROKE);
canvas.drawArc(new RectF(width / 2 - insideArcRadius, radius - insideArcRadius, width / 2 + insideArcRadius, radius + insideArcRadius),
(float) (180 - floatAngel),
(float) (180 + 2 * floatAngel), false, paint);
}
三、绘制进度条的渐变色
绘制渐变色的进度条主要是用到了setXfermode()方法setShader()方法和来进行绘制,setXfermode方法选择PorterDuff.Mode.SRC_ATOP是用于将绘制的内容显示在第一次绘制内容之上,(不过这个绘制应该在Bitmap上,最后的整体代码上有),setShader方法用于渐变色控制
四、绘制最外层的的原点
最外层的原点需要不断的计算坐标,在这里用到的方法主要是PathMeasure类,将要绘制的圆弧,加入一个路径,
private float[] pos; // 当前点的实际位置
private float[] tan; // 当前点的tangent值,
PathMeasure measure = new PathMeasure(orbit, false);
measure.getPosTan(measure.getLength() * 1, pos, tan);
获取路径的终点的正切值和坐标,然后根据坐标点绘制实心小园球
private void paintPercent(double percent,double aimPercent,Canvas canvas){
double roateAngel=percent*0.01*225;
shaderPaint.setColor(yellowColor);
shaderPaint.setStrokeCap(Paint.Cap.ROUND);
shaderPaint.setAntiAlias(true);
shaderPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_ATOP));//shaderPaint.setColor(yellowColor);
if (aimPercent>=0&&aimPercent<=20){
}else if (aimPercent>20&&aimPercent<=60){
int colorSweep[] = { yellowColor,pinkRedColor };
float position[]={
0.5f,0.7f};
SweepGradient sweepGradient=new SweepGradient(width / 2, radius, colorSweep, position);
shaderPaint.setShader(sweepGradient);
}else if (aimPercent>60&&aimPercent<=90){
int colorSweep[] = { yellowColor,pinkRedColor,redColor };
float position[]={
0.5f,0.7f,0.8f};
SweepGradient sweepGradient=new SweepGradient(width / 2, radius, colorSweep, position);
shaderPaint.setShader(sweepGradient);
}else if (aimPercent>90){
int colorSweep[] = {deepRedColor, yellowColor,yellowColor,pinkRedColor,redColor, deepRedColor};
float position[]={
0.2f,0.4f,0.5f,0.7f,0.9f,1.0f};
SweepGradient sweepGradient=new SweepGradient(width / 2, radius, colorSweep, position);
shaderPaint.setShader(sweepGradient);
}
if (aimPercent<=10){
//目的是为了
drawInsideArc((float) (180 - floatAngel), (float) roateAngel, canvas);
drawOuterAcr((float) (180 - floatAngel), (float) roateAngel, canvas,mBitmapBackDeepRed,yellowColor);
}else if (aimPercent>10&&aimPercent<=20){
drawInsideArc((float) (180 - floatAngel), (float) roateAngel, canvas);
drawOuterAcr((float) (180 - floatAngel), (float) roateAngel, canvas,mBitmapBackDeepRed,yellowColor);
}else if (aimPercent>20&&aimPercent<=60){
drawInsideArc((float) (180 - floatAngel), (float) (roateAngel-(spaceAngle-floatAngel)), canvas);
drawOuterAcr((float) (180 - floatAngel), (float) (roateAngel - (spaceAngle - floatAngel)), canvas,mBitmapBackDeepRed,pinkRedColor);
}else if (aimPercent>60&&aimPercent<=90){
drawInsideArc((float) (180 - floatAngel), (float) (roateAngel-(spaceAngle-floatAngel)), canvas);
drawOuterAcr((float) (180 - floatAngel), (float) (roateAngel - (spaceAngle - floatAngel)),canvas,mBitmapBackDeepRed,redColor);
}