Android 仪表盘View

本文介绍了如何在Android中创建一个动态的仪表盘视图,包括使用线段旋转和同心圆绘制圆弧,以及处理指针随手指移动的越界情况。涉及到数学知识如正切函数,以及Canvas的使用。示例代码展示了具体的实现细节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

导语

这里展示的View估计项目中多半是用不到的,只是用来加深理解的。文章末尾会有全部的代码,如果想研究可以复制过去直接运行,不需要额外的资源。

先看效果:
这里写图片描述
这里指针是通过手指来改变方向的,并不能通过数字参数来改变,如果需要,可以更改相应的代码。

需要的数学知识

理论的涉及也非常简单,如下所示:

  1. 在坐标系中,一个点与原点连线与X轴的正切值 tan = 点的纵坐标 ÷ 点的横坐标
  2. 在每一个象限中,正切函数是单调函数;如图所示:
    这里写图片描述

绘制流程

绘制由线段组成的圆弧

这里写图片描述

利用线段的旋转来绘图

绘制上图有多种方法,首先介绍一种简单的方法:
将线段旋转多个角度,这样可以绘制出一个圆弧型:

private int width;
private int height;

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    canvas.translate(width / 2, height / 2);
    Paint mPaint = new Paint();
    mPaint.setStrokeWidth(5);
    for (int i = 0; i <= 360; i += 5) {               // 绘制圆形之间的连接线
        canvas.drawLine(0, 120, 0, 200, mPaint);
        canvas.rotate(10);
    }
}

@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    super.onSizeChanged(w, h, oldw, oldh);
    width = w;
    height = h;
}

上述代码的执行效果:
这里写图片描述
虽然丑了点,但可以说明问题。不过这样做,我们缺乏对弧形的控制。例如:如何实现圆弧呢?是不是要手动计算起始坐标,旋转的角度,扫过的角度等各种各样的问题?因为怕麻烦,这个方案就被我华丽的抛弃了。

利用两个同心圆来绘制

这里写图片描述

思路:

  1. 从圆心发射一条射线出来,与两个圆相交于点A和点B,链接A与B,就可以划出一条我们想要的线段。
  2. 均匀的发射多条射线,我们就可以得到一个由线段组成的圆弧。
  3. 如果两个圆圈是圆弧的话,就可以达到我们所要的效果

所以,最终确定的步骤为:

  1. 画一个大圆弧
  2. 画一个缩小版的小圆弧
  3. 均匀地在两个圆弧之间画线段

用动态图来展示下:

这里写图片描述
相关代码比较多,在文章末尾已经贴出来了(88-172行,代码中有后续的细节处理,需要甄别下相关的代码),这里只是写下思路,不再重复贴代码了

画个一个长度固定、原点确定,方向随着手指变化的指针

这里写图片描述
这步要实现的效果如上图所示

假设,之前的指针为OZ,现在我们用手指触摸了点A,这时我们希望指针变为OB,那么,该如何实现呢?

  1. 获取A点的坐标(通过onTouchEvent()可以获取到)
  2. 画取线段OA(O点为(0,0),所以可以画取)
  3. 通过测量OA,可以利用PathMeasure.getPosTan()来获取B点的坐标(指针的长度是固定的)
  4. 在Cavas中画OB线段
    这里写图片描述

如果我们触摸点为X,距离过短怎么办呢?

  1. 链接OX,并用MeasurePath来测量OX的长度,以及X的坐标(a,b)
  2. 计算OY与OX的比例 R = OY ÷ OX
  3. 计算Y点的坐标 x = a × R, y = b × R
  4. 在Cavas中画OY线段
    这里写图片描述
    相关代码同样比较多,在文章末尾已经贴出来了(179-242行,代码中有后续的细节处理,需要甄别下相关的代码),这里只是写下思路,不再重复贴代码了

处理越界的情况

这里写图片描述
上图情况是我们不想看到。如果指针偏到最右边,就不能再往下偏了;左边同理。这个时候,就需要想到tan函数的性质:

在每一个象限中,正切函数是单调函数

这里写图片描述

说明下:

  1. 在第二象限中,当前的tan值小于边界OA的tan值a时,说明此时是在边界外面;如果大于a,说明在边界里面
  2. 在第一象限中,当前的tan值大于OB的tan值b时,说明在边界外面;如果小于b,说明在边界里面
    这里写图片描述

知道上述知识后,就非常好处理,具体过程如下:

  1. 在绘制弧形时,记录下左侧边界的tan值和右侧边界的tan值(下面代码129-151行)
  2. 在第一象限和第二象限时,记录下当前位置的tan值,并与边界的tan值进行比较来判断是否在边界中:(下面代码214-233行)
    • 在边界中,不做处理
    • 在边界外,指针根据情况指向点A或者点B
  3. 绘制出相应的指针<
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值