1.成品展示11122
2.思路分析
这是一个很简单的仪表盘较为简单单调的仪表盘。
第一步,我们要画一个弧形(Canvas.drawArc())。
第二步,画出均匀刻度。
第三步,画指针。
3.具体实现
3.1 画弧形
//1,画弧形
//角度
private static final int ANGLE = 120;
//半径
private static final float RADIOUS = DpToPxUtil.dp2px(150);
//刻度盘弧形宽度
private static final float dashBoardWidth = DpToPxUtil.dp2px(2);
private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
{
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeWidth(dashBoardWidth);
}
canvas.drawArc(getWidth()/2 - RADIOUS,getHeight()/2 - RADIOUS,getWidth()/2 + RADIOUS,getHeight()/2 + RADIOUS,90 + ANGLE/2,360 - ANGLE,false,mPaint);
3.2.画刻度
画刻度,这里需要PathDashPathEffect (PathDashPathEffect 详解 2.5.4)
mPath.addRect(0,0,DpToPxUtil.dp2px(2),DpToPxUtil.dp2px(10),Path.Direction.CW);
mPathDashPathEffect = new PathDashPathEffect(mPath,50,0,PathDashPathEffect.Style.ROTATE);
mPaint.setPathEffect(mPathDashPathEffect);
效果
这里我们看到他只是画出了虚线的刻度盘,因为这里PathDashPathEffect并不是给我们添加一个特效,而是将我们绘制的效果改成我们所需要的效果。所以这里我们需要先画一次圆弧,然后再添加特效。
3.2.1.添加弧形
mPaint.reset();
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeWidth(dashBoardWidth);
canvas.drawArc(getWidth()/2 - RADIOUS,getHeight()/2 - RADIOUS,getWidth()/2 + RADIOUS,getHeight()/2 + RADIOUS,90 + ANGLE/2,360 - ANGLE,false,mPaint);
3.2.2.添加刻度
//添加虚线刻度
mPath.addRect(0,0,DpToPxUtil.dp2px(2),DpToPxUtil.dp2px(10),Path.Direction.CW);
//测量弧形长度
mPathArc.addArc(getWidth()/2 - RADIOUS,getHeight()/2 - RADIOUS,getWidth()/2 + RADIOUS,getHeight()/2 + RADIOUS,90 + ANGLE/2,360 - ANGLE);
mPathMeasure = new PathMeasure(mPathArc,false);
mPathDashPathEffect = new PathDashPathEffect(mPath,mPathMeasure.getLength()/20,0,PathDashPathEffect.Style.ROTATE);
//2.画刻度
mPaint.setPathEffect(mPathDashPathEffect);
canvas.drawArc(getWidth()/2 - RADIOUS,getHeight()/2 - RADIOUS,getWidth()/2 + RADIOUS,getHeight()/2 + RADIOUS,90 + ANGLE/2,360 - ANGLE,false,mPaint);
注:这里有一个地方需要注意。
这里我们需要画20个刻度,所以我们需要先测量出弧形的总长度,然后除以20,然后的出刻度的间隙,然后再画出刻度。这样的结果如图
这里注意到最后一个刻度没有画出来!!!
这里是因为我们的刻度是有宽度的,当我们计算刻度的间距的,我们需要20个间距,21个刻度值,所以我们这里计算间距的时候,应该用弧形的长度减去最后一个刻度的宽度然后再除以20;
//测量弧形长度
mPathArc.addArc(getWidth()/2 - RADIOUS,getHeight()/2 - RADIOUS,getWidth()/2 + RADIOUS,getHeight()/2 + RADIOUS,90 + ANGLE/2,360 - ANGLE);
mPathMeasure = new PathMeasure(mPathArc,false);
mPathDashPathEffect = new PathDashPathEffect(mPath,(mPathMeasure.getLength() - DpToPxUtil.dp2px(2))/20,0,PathDashPathEffect.Style.ROTATE);
嘿嘿,好了,你说气人不!!!
3.3 画指针
//3.画指针
canvas.drawLine(
getWidth()/2,
getHeight()/2,
getWidth()/2 + (float)Math.cos(Math.toRadians(getCurrentMark(14))) * pointLength,
getHeight()/2 + (float)Math.sin(Math.toRadians(getCurrentMark(6))) * pointLength,
mPaint);
这里画指针需要获取指针所对应的刻度的角度,这里对应这个这个仪表盘的刻度封装了对应的方法。
//获取对应刻度的角度
private int getCurrentMark(int mark){
return (int)(90 + (float)ANGLE/2 + (360 - (float)ANGLE)/20 * mark);
}
这里因为指针是从弧形刻度的左下角开始的,所以要先加上弧形起始角度(90 + (float)ANGLE/2)。
随后,根据用户给出的刻度值mark,然后计算出对应刻度所占的角度大小( (360 - (float)ANGLE)/20 * mark)。
然后将两个值相加,得到mark所都对应的角度值。
附:
这里 DpToPxUtil.dp2px(2) 为dp 像素转换工具类
public static float dp2px(float dp){
return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,dp, Resources.getSystem().getDisplayMetrics());
}
到此,简单的仪表盘做好了!
Demo:CMViewDemo Github地址