Gtihub传送门 |
---|
在个人
Github
开源库中,今天刚写好了一个饼图的绘制,这里主要就是对饼图绘制的一个讲解了。ios
以前咱们讲过了一个Path
,可是若是全用Path
去实现,也不是说不可以实现,可是并不适用于不少的场景状况。git
这里的话,咱们主要讲的就是关于Canvas
的使用了。以前咱们在Path
中用到过这样的一个函数moveTo
,也就是把路径从当前的位置移动到新的坐标上。那咱们的Canvas
是否有这样的功能呢?github
天然是有的了,这里直接做出一个解答,他的函数就是translate
,可是有一点要注意!!!这个函数是一个相对移动,而不是绝对移动。canvas
canvas?.translate(60f, 80f)
paint?.let { canvas?.drawCircle(0f, 0f, 100f, it) }
canvas?.translate(60f, 80f)paint?.color = Color.BLUE
paint?.let { canvas?.drawCircle(0f, 0f, 100f, it) }
复制代码
上述就是实现代码以及一个贴图了。你能够直观的感觉到这个移动实际上是基于当前的基础来完成的。可是读者会说了,这种效果彻底可让我经过Path
来完成啊,不必经过Canvas
,ok,确实能够,你也能够经过Path
来实现。函数
可是难点如今才来,下图的样式该怎么实现??工具
在知道怎么写代码以前,那咱们要知道确定是他的组成成分究竟是什么了。布局
若是让咱们直接去获取绝对坐标,而后进行绘制,那是否是会很是麻烦呢?因此这里要引入一个Canavs
的操做方法。post
Canvas
操做在使用以前须要注意,画布是须要保存的,否则画布将不断的保留上一次的状态进行绘制,那总体就会呈现一种叠加混乱的局面。而这个方法就是save()
和restore()
的成对使用。学习
for (i in 0..2) {
canvas?.save()
paint?.color = Color.BLUE
canvas?.translate(60f, 80f)
canvas?.scale(0.5f, 0.5f)
paint?.let { canvas?.drawCircle(0f, 0f, 100f, it) }
canvas?.restore()
}
复制代码
使用前 | 使用后 |
---|---|
![]() |
![]() |
你能够把这个操做理解为画布归位,或者说画布重置。而这个重置对应的就是保存了save()
以前的操做过程。ui
Scale
这个效果再也不赘述了。
Rotate
和其余的都是同样的会有两种画布的操做函数
canvas?.save()
paint?.color = Color.BLUE
canvas?.translate(60f, 80f)
canvas?.rotate(45f)
// 以自身中心做为圆点旋转
// canvas?.rotate(45f,30f, 40f)
paint?.let { canvas?.drawRect(0f, 0f, 100f, 100f, it) }
canvas?.restore()
复制代码
饼图的实现其实就是基于这个函数来完成的。
Shew
和其余的不一样了,他并再也不经过咱们的坐标圆心,而是对标咱们X
和Y
轴
canvas?.save()
paint?.color = Color.BLUE
canvas?.translate(60f, 80f)
canvas?.skew(0f, 1f)
paint?.let { canvas?.drawRect(0f, 0f, 100f, 100f, it) }
canvas?.restore()
复制代码
传入的数据其实就是分别与X
和Y
轴的正切值,经过截图工具,你可以明显的发现这个问题。画了绿色框框的部分,你能够看到的是正好一个45度的大小。
经过画图你也能够这样理解,就是Y
轴顺时针方向旋转45度。
基本就是以上问题,问题1我已经作出来回答,后续两个问题将一个个做出解释。
在个人代码中,其实分为两块,一是圆弧,一是介绍,这也是他们的绘制顺序了。可是须要考虑一个问题:介绍线的位置肯定?
这个问题你须要看一下个人图例了,你有没有注意到,个人介绍线,好像都是关于单个圆弧居中的呢?
那咱们的方案其实就来了,上面咱们讲到过了什么?Rotate
还记得这个函数嘛!!经过数据运算,有了每一个圆弧的大小,那咱们还不能去进行绘制嘛?不就是先划线,再旋转吗。而后旋转就是这样的一个公式要去计算。
// 旋转角度 = 前面的弧度 + 当前弧度的一半
private fun getRatioSum(j: Int): Float {
var sum = 0f
for (i in 0 until j) {
sum += mRatios!![i]
}
return sum
}
private fun getRatioHalfSumDegrees(j: Int): Float {
var sum = getRatioSum(j)
sum += mRatios!![j] / 2
return sum * 360
}
复制代码
跟前面的圆弧同样,可是是一个个圆弧来组成圆,那这个时候,就是要知道前面的弧度,而后对当前的弧度的计算,也就是扫过的区间进行计算了。
private fun drawArc(canvas: Canvas) {
val drawArc = 360 * scale
for (i in mRatios!!.indices) {
mArcPaint?.color = mArcColors!![i]
mArcPaint?.let {
canvas.drawArc(
arcRect!!,
getRatioSum(i) * drawArc,
mRatios!![i] * drawArc,
true,
it
)
}
}
}
复制代码
基本上就是靠上述的两个来完成的,是否是仍是比较简单的呢。冲冲冲,Demo
抄起来,你就有一份本身的饼图绘制了。
以上就是个人学习成果,若是有什么我没有思考到的地方或是文章内存在错误,欢迎与我分享。
相关文章推荐: