您的位置:首页 > 移动开发 > Android开发

自定义圆形进度条(二)

2017-07-16 14:42 176 查看
有一定自定义View基础的人可以看懂attr文件和TypeA类,但是可能会对坐标和测量有疑惑

1 圆的半径在哪里?



如上图所示,这是一个圆环,很多人看到自定义View计算距离觉得很懵逼其实就是在这里遇到一个坑,你是不是以为圆的半径是OA或者OC?因为按照图上所显示,确实有两个圆啊,一个大圆一个小圆,那半径不就应该是OA和OC么?



看到这张图我相信大多人明白了一些道理,其实整个绘制只画了一个圆,半径就是OB,AB=BC,为什么会这样?其实是没有重视这个方法 paint.setStrokeWidth(progressWidth),我们使用Paint绘制的只是OB这个圆,但是如果你设置了宽度的话就会使得这个B圆边变粗,变得长度等于AB,所以看起来是一个圆环,其实本质还是以OB为半径。

结合我们的代码理解下:

width = (int) ((2 * circleRadius) + progressWidth);
//这里计算View宽度其实就是两个半径+画笔的宽度(AC/2+OB*2+AC/2)


2 圆形角度是多少?



在Android坐标系中,x轴向右为正,y轴向下为正,所以

0度角是 OB-OB

90度角是 OB-OC

-90度角 是 (O-C)-(OB)

剩余的角度可以类比推出

结合我们的代码理解下:

canvas.drawArc(oval, -90, 360 * (progress / maxProgress), false, paint);
//从竖直方向(12点钟方向)开始画弧形,所以这里是-90,false是为了不让圆弧和圆心相连接,只画弧BC,设置true的话就会显示成OBC弧


3 drawText有点复杂

我们小时候写字为了限制大小保证对齐都需要使用五线谱的本子写



其实机器也是这么笨拙,让她写字她也需要有五线谱,大家可以看到倒数第二行基本上是所有字母的最底部,这个最底部的术语叫做“基线”,写字的时候以基线为参照线来写,如果比基线高那么就往上写,低的话就往下写。

与之类似,Android也有这五条线,ascent,descent,top,bottom,baseline

这五条线怎么获得又有什么用呢?

Android给我们提供了一个类:FontMetrics,它里面有四个成员变量:

FontMetrics::ascent

FontMetrics::descent

FontMetrics::top(注意!和我们理解的顶部y轴坐标不一样)

FontMetrics::bottom(注意!和我们理解的底部y轴坐标不一样)



看到这里需要解释这四个有什么关系,术语不说了,打个比方吧

整个TextView是一个电视机,电视机高就是(top和bottom之间的距离),但是不可能电视机多大,显示屏就多大,显示屏的高度是(ascent和descent之间的距离),我们按照基线(baseline)播放图像,保证能在显示屏内部显示。

结合源码理解下:

int baseline = (getMeasuredHeight() - fontMetrics.bottom + fontMetrics.top) / 2 - fontMetrics.top;  //获得文字的基准线y轴坐标




已知fontMetrics.top,fontMetrics.bottom,和整个View的高度,我们的目标是获得基线(b1-b2)线段的y轴坐标!

1 既然知道fontMetrics.top,那么只需要知道textview的top坐标既可以知道baseline横坐标

2 既然知道总高度和文本视图的高度,那么就可以知道textview的top坐标(A的y轴坐标)

脑筋没转过来那我们一点点写:

(getMeasuredHeight() - fontMetrics.bottom + fontMetrics.top) / 2=

(getMeasuredHeight() - (fontMetrics.bottom - fontMetrics.top)) / 2=

(2*OR-AB)/2=

OR-OA=RA

等于TextView顶部的y轴坐标,既然知道了A的y轴坐标就可以求出基线的y轴坐标!

以上就是关于圆形进度条里面的最让人疑惑不解的地方,不足之处恳请勘误,如果有其他的疑问可以在文章下方留言,我会及时回复哒!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息