自定义圆形进度条(二)
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为半径。
结合我们的代码理解下:
2 圆形角度是多少?
在Android坐标系中,x轴向右为正,y轴向下为正,所以
0度角是 OB-OB
90度角是 OB-OC
-90度角 是 (O-C)-(OB)
剩余的角度可以类比推出
结合我们的代码理解下:
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)播放图像,保证能在显示屏内部显示。
结合源码理解下:
已知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轴坐标!
以上就是关于圆形进度条里面的最让人疑惑不解的地方,不足之处恳请勘误,如果有其他的疑问可以在文章下方留言,我会及时回复哒!
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轴坐标!
以上就是关于圆形进度条里面的最让人疑惑不解的地方,不足之处恳请勘误,如果有其他的疑问可以在文章下方留言,我会及时回复哒!
相关文章推荐
- 自定义View之音频播放圆形进度条
- Android自定义View之可随时暂停、开启的圆形下载进度条
- Android 自定义圆形进度条
- andriod自定义view 小案例(带进度的圆形进度条)
- [置顶] 自定义view之圆形进度条
- 自定义View实现Android圆形进度条
- Android 高手进阶,自定义圆形进度条
- android_studio的自定义View的圆形进度条
- Android自定义实现圆形播放进度条
- Android 高手进阶之自定义View,自定义属性(带进度的圆形进度条)
- 自定义绘制圆形和弧形进度条
- Android 高手进阶之自定义View,自定义属性(带进度的圆形进度条)
- Android自定义view圆形进度条
- flex可自定义圆形加载进度条例子代码下载
- Android 高手进阶之自定义View,自定义属性(带进度的圆形进度条)
- Android 自定义View,自定义属性--自定义圆形进度条(整理)
- Android 高手进阶之自定义View,自定义属性(带进度的圆形进度条)
- Android高手进阶之自定义View,自定义属性(带进度的圆形进度条)
- 自定义圆形进度条
- Android自定义圆形渐变进度条(续)--加动画