1.写在前面
项目中做了个仪表盘效果,需要支持在java中实时更改最大值以及当前值,效果图如下
同时我这里处理了下,让它可以支持float类型的数据
2.实现
首先这个自定义view没有涉及事件分发和动画,纯粹全部都是draw,所以是个练手的好机会。对这个view分析下,可以分为如下几部分
我们需要做的就是按部就班的全部画出来即可。
2.1 外弧
我这里方法可能一别人不一样,我首先就移动了画布,将画布的移动到view的中心,所以中心坐标是(0,0),我觉得这样子后面坐标点的坐标好算点。
//整个view的长 宽
private int mWidth,mHeight;
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mWidth = w;
mHeight = h;
/**
* 圆弧外切矩形的宽度,圆弧的半径即为它的一半
*/
mRectWidth = (float) (Math.min(mWidth,mHeight)*0.9);
}
/**
* 将圆心移到控件中间
*/
canvas.translate(mWidth / 2, mHeight / 2);
上方的Math.min(x,y)*0.9是 正方形类自定义view的常规处理,毕竟这种view的长宽设置时一般都是一样的,但是万一设置的不一样,就取最小的同时在缩小点,留点padding
第一步当然画如上图的弧,我为了更明显,红色的坐标系是我加上过去的。这个弧比较容易画,比较明显弧的起始角度是135,弧扫过的角度是270
/**
* 画圆弧
* @param canvas
*/
private void drawArc(Canvas canvas){
mArcPaint.setStyle(Paint.Style.STROKE);
RectF rectFArc = new RectF(-mRectWidth / 2, -mRectWidth / 2, mRectWidth / 2, mRectWidth / 2);
canvas.drawArc(rectFArc,mStartAngle,mSweepAngle,false,mArcPaint);
}
一般来说,画圆弧的第一步是获取圆弧的外切矩形,比如上的rectFArc
2.2 画短刻度
这里为什么是先画短刻度,而不是长刻度,我这里的处理是一共分为十个大份,每个大份分为十个小份,其实长刻度是属于短刻度的,属于包含关系,所以我先讲短刻度画出来,然后长刻度覆盖即可。画短刻度的思路是,先找出短刻度两个点的坐标,然后将两个点这条线画出来,在通过画布旋转。
如上图所示