Android绘图系列(三)——自定义View绘制仪表盘

这个系列主要是介绍下Android自定义View和Android绘图机制,自己能力有限,如果在介绍过程中有什么错误,欢迎指正

前言

在上一篇Android绘图系列(二)——自定义View绘制基本图形中我们可以绘制一些基本的图形了,这篇我们就来综合画一个仪表盘

效果图

Android绘图系列(三)——自定义View绘制仪表盘_第1张图片

绘制前准备

在绘制这个仪表盘之前我们得先说下.Canvas的操作

相关操作 简要介绍
save 保存当前画布状态
restore 回滚到上一次保存的状态
translate 相对于当前位置位移
rotate 旋转

首先,我们来看一下前面两个方法

在讲解这两个方法之前,首先来了解一下Android绘图的坐标体系,这个其实这个前面已经讲了,这里不赘述,而Canvas.save()这个方法,从字面上的意思可以理解为保存画布,他的作用就是讲之前的图像保存起来,让后续的操作能像在新的画布一样操作,这跟PS的图层基本差不多

而Canvas.restore()这个方法,则可以理解为合并图层,,就是将之前保存下来的东西合并

而后面两个方法,从字母上理解画布平移或者旋转,但是把他理解为坐标旋转更加形象,前面说了,我们绘制的时候默认坐标点事左上角的起始点,那么我们调用translate(x,y)之后,则将原点(0,0)移动到(x,y)之后的所有绘图都是在这一点上执行的,这里可能说的不够详细,相信我们绘制完今天的例子就会有一个理解的

绘制步骤

  • 1.仪表盘——外面的大圆盘
  • 2.刻度线——包含四个长的刻度线和其他短的刻度线
  • 3.刻度值——包含长刻度线对应的大的刻度尺和其他小的刻度尺
  • 4.指针——中间的指针,一粗一细两根

实际操作

1.第一步 绘制外面的仪表盘

这里我们取圆心为屏幕宽度一半,屏幕高度一半,半径是屏幕宽度一半

**
 * Created by HFS on 2017/2/5.
 * 仪表盘
 */

public class CircularView extends View {
    // 宽高
    private int mWidth;
    private int mHeight;

    // 构造方法
    public CircularView(Context context, AttributeSet attrs) {
        super(context, attrs);
        // 获取屏幕的宽高
        WindowManager wm = (WindowManager) getContext().getSystemService(
                Context.WINDOW_SERVICE);
        mWidth = wm.getDefaultDisplay().getWidth();
        mHeight = wm.getDefaultDisplay().getHeight();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        // TODO Auto-generated method stub
        super.onDraw(canvas);

        // 画外圆
        Paint paintCircle = new Paint();
        paintCircle.setAntiAlias(true);
        paintCircle.setStyle(Paint.Style.STROKE);
        paintCircle.setStrokeWidth(5);
        canvas.drawCircle(mWidth / 2, mHeight / 2, mWidth / 2, paintCircle);

    }

}

效果

Android绘图系列(三)——自定义View绘制仪表盘_第2张图片

绘制刻度线和刻度值

下面,我们来画刻度尺,这个也很简单,一条线而已,只要确定两个端点的位置就可以,第一根线还是比较容易确定的,那后面的我们怎么去确定尼?那些斜着的我们可以用三角函数去实现计算,但是这其实就是一个很简单的画图,三角函数的运算也要这么多,我们不经要思考,该怎么去简化他呢?其实Google已经为我们想好了

我们觉得这个不好画,主要是这个角度,那么如果我们将画布以中心为原点旋转到需要的角度尼?每当画好一根线,我们就旋转多少级角度,但是下一次划线的时候依然是第一次的坐标,但是实际上我们把画布重新还原到旋转钱的坐标了,所有的刻度线就已经画好了,通过旋转画布——实际上是旋转了画图的坐标轴,这就避免了万恶的三角函数了,通过这样一种相对论式的变换,间接简化了绘图,这时再去绘制这些刻度,是不是要简单了,只需要区别整点和非整点的刻度了


        // 画刻度
        Paint paintDegree = new Paint();
        paintDegree.setStrokeWidth(3);
        for (int i = 0; i < 24; i++) {
            // 区别整点和非整点
            if (i == 0 || i == 6 || i == 12 || i == 18) {
                paintDegree.setStrokeWidth(5);
                paintDegree.setTextSize(30);
                canvas.drawLine(mWidth / 2, mHeight / 2 - mWidth / 2,
                        mWidth / 2, mHeight / 2 - mWidth / 2 + 60, paintDegree);
                String degree = String.valueOf(i);
                canvas.drawText(degree,
                        mWidth / 2 - paintDegree.measureText(degree) / 2,
                        mHeight / 2 - mWidth / 2 + 90, paintDegree);
            } else {
                paintDegree.setStrokeWidth(3);
                paintDegree.setTextSize(15);
                canvas.drawLine(mWidth / 2, mHeight / 2 - mWidth / 2,
                        mWidth / 2, mHeight / 2 - mWidth / 2 + 30, paintDegree);
                String degree = String.valueOf(i);
                canvas.drawText(degree,
                        mWidth / 2 - paintDegree.measureText(degree) / 2,
                        mHeight / 2 - mWidth / 2 + 60, paintDegree);
            }
            // 通过旋转画布简化坐标运算
            canvas.rotate(15, mWidth / 2, mHeight / 2);
        }

效果

Android绘图系列(三)——自定义View绘制仪表盘_第3张图片

绘制指针

就是两条直线

    // 画指针
        Paint paintHour = new Paint();
        paintHour.setStrokeWidth(20);
        Paint paintMinute = new Paint();
        paintMinute.setStrokeWidth(10);
        canvas.save();
        canvas.translate(mWidth / 2, mHeight / 2);
        canvas.drawLine(0, 0, 100, 100, paintHour);
        canvas.drawLine(0, 0, 100, 200, paintMinute);
        canvas.restore();

效果
Android绘图系列(三)——自定义View绘制仪表盘_第4张图片

OK,这样一个仪表盘就绘制完了

Github地址

你可能感兴趣的:(Android自定义View)