首页文章android 简单饼图 用手机做饼状图手机记账本「android 简单饼图 用手机做饼状图」

android 简单饼图 用手机做饼状图手机记账本「android 简单饼图 用手机做饼状图」

时间2025-01-16 17:50:18发布yu分类文章浏览141
导读:本文要介绍的是一个参照手机支付宝app里面记账本功能里的“饼状图”实现的控件。通常app中可能的数据展示控件有柱状图,折线图,饼状图等,如果需要一个包含多种View控件的库,那么 MPAndroidChart 是不错的选择,如果只是需要一个简单的独立的饼状图控件,希望PieGraphView满足你的要求。目前实现的饼状图的效果如下所示,和支付宝app记账本中...


本文要介绍的是一个参照手机支付宝app里面记账本功能里的“饼状图”实现的控件。通常app中可能的数据展示控件有柱状图,折线图,饼状图等,如果需要一个包含多种View控件的库,那么 MPAndroidChart 是不错的选择,如果只是需要一个简单的独立的饼状图控件,希望PieGraphView满足你的要求。

目前实现的饼状图的效果如下所示,和支付宝app记账本中的功能基本一样:




android 简单饼图 用手机做饼状图_移动开发



  • 展示的数据
    可以展示多组数据(ItemGroup),每次展示一组数据,一组数据对应形成一个圆环。一组数据由多个Item组成,对应圆环中的扇形。
  • 圆环
    一个ItemGroup最终显示为一个圆环。它的中的items是包含的数据项。这些数据项根据其value占总数据的比例对应不同的扇形角度。ItemGroup的所有Item依次绘制,形成360°。
  • 起始角度和旋转
    所有角度值是X正轴开始顺时针增加。圆环有一个开始角度使用字段mStartAngle表示,所有扇形的绘制是从mStartAngle开始的,它是0-360度的数值,例如可以设置为90让绘制从正下方开始等。圆环可以旋转,旋转是针对mStartAngle而言的。
  • 选中并高亮Item
    点击可以选择一个扇形,选中的扇形作为“当前项”,使用字段记录它的索引。选择一个扇形后,它会旋转其中间角度到mStartAngle的角度,然后对应扇形执行“grow”动画进行高亮突出。
  • 切换ItemGroup
    点击圆环内部可以切换显示不同的ItemGroup。切换会有一个动画,先是顺时针从mStartAngle绘制整个圆环。之后在自动选中最后一个Item。

圆环的绘制实际就是通过先后绘制两个半径不同的圆实现,圆就是360度的扇形,canvas.drawArc提供了这个功能:

需要先绘制有颜色的外圆对应的各个扇形,之后再“覆盖”绘制内圆对应的各个扇形。

绘制圆环的时候需要考虑开始角度mStartAngle和当前的旋转mRotation。这里设计了一个方法drawPieFromEnd用来在(start, end)的角度范围内绘制“被显示”的那些扇形。这里的角度是扇形数组的形成的0-360的连续角度范围。

为了绘制的简单,方法选择从最后一个扇形开始绘制,相当于从end绘制到start,这样的好处是不用去计算实际上start对应的是哪个扇形了,而根据传递的角度范围,当下一个绘制的扇形的起始角度大于start时,结束绘制:

当前控件交互过程中总共有三个动画:

  • showOut
    每个ItemGroup显示时执行切换动画。
  • rotate
    旋转动画,被选中的Item会旋转其中心角度到mStartAngle。
  • grow
    被选中的扇形旋转结束后,或者再次点击当前已选扇形,就对它执行一次grow动画,使得扇形高亮突出。

所有动画通过Animation实现,这里只是使用Animation完成动画时间和进度的控制。
重写applyTransformation方法来记录当前动画的进度progress,然后invalidate通知onDraw的执行。
开始动画执行时将当前动画模式字段设置为不同的ANIM_MODE_xxx常量,然后onDraw中会根据当前的mAnimMode值,选择对应动画的绘制方法去执行。

代码结构如下:

方法中对动画进行初始化。执行来开启动画。onDraw方法中根据动画模式选择执行不同的绘制方法。
三个动画都是这样的设计思路。

mStartAngle和mRotation两个字段的值决定了绘制圆环的起始角度。这里旋转的方式不能是执行View.setRotation()方法,因为会旋转整个View的区域——View的坐标跟着旋转!!!使得之后点击事件的处理会比较麻烦。
旋转每次只需要计算“要旋转到的目标角度”和“当前已旋转的角度”的差值,然后执行旋转动画,不断修改mRotation值执行onDraw即可:

上面旋转角度控制在(-360, 360),和扇形相关的角度控制在(0, 360)。

选择的扇形记录其对应Item的索引,只有在没有任何动画执行时,或者是正在执行grow动画时才会对当前选择的扇形进行突出显示。
绘制的思路是改变要突出的扇形角度对应的扇形的外圆、内圆的区域大小(drawArc中的oval参数),也就是修改drawArc方法需要的椭圆的矩形区域:

上面绘制的顺序是:

  1. 绘制所有扇形的外圆扇形,当前项的半径会不同。
  2. 绘制对应当前扇形角度的内圆的扇形。
  3. 绘制除去当前扇形角度的其余角度的内圆的扇形。

grow动画又分为加粗(GROW_MODE_BOLD)和向外移动(GROW_MODE_MOVE_OUT)两个动画,不同动画时内圆扇形的半径不同,上面因为float值得原因扇形可能会有缝隙,为了消除这个缝隙,最终在绘制的时候会让“当前扇形的绘制”或者“剩余圆环部分”的绘制直接是绘制360度,因为最终的扇形的确存在包含关系。

重写onTouchEvent方法,根据ACTION_DOWN时的(x, y)来确定点击区域是发生在圆环内部、圆环上、还是圆环外。之后会执行不同的处理。

只有在动画未执行时处理点击事件。这里只是简单的监听手指按下的动作,如果为了“更自然”的监听,可以在ACTION_UP中根据前后的坐标变动来选择是否判定为对饼状图的有效点击。也可以结合OnClickListener处理“click”事件。总之,关键是获得点击的(x, y)坐标。

方法calcClickItem完成了点击事件的不同处理:如果点击发生在内圆就切换显示的ItemGroup,点击发生在圆环外不处理。点击圆环上某个扇形后,就设置扇形对应的Item为“当前项”,对应扇形会被旋转到mStartAngle的位置,旋转后执行grow动画进行突出显示。

根据点击的坐标(x, y)和圆心(centerX, centerY)可以计算出点击的点相对圆心的角度。下面方法calcAngle完成此任务。

代码如下:

上面的方法calcClickItem根据此角度,结合当前圆环的mStartAngle、mRotation就可以确定点击落在的扇形区域了。

绘制扇形过程中,可以得到扇形的中间角度middleAngle,而中心的半径就是圆环外半径减去一半圆环宽度,使用GeomTool.calcCirclePoint工具方法,可以根据“圆心、半径、角度”计算出扇形中心点的坐标。

代码如下:

目前没有添加任何attribute,方便单一类文件的阅读。
在布局文件中可以声明PieGraphView对象,然后Activity中可以对它设置数据,设置圆环宽度等。主要有下面几个方法:

  • public void setData(ItemGroup[] groups)
    设置要显示的数据。
  • public void setRingWidthFactor(float factor)
    设置圆环宽度
  • public void setGrowWidthFactor(float factor)
    设置圆环上某个Item可以grow的额外半径。

台湾版权声明:本网信息来自于互联网,目的在于传递更多信息,并不代表本网赞同其观点。其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,并请自行核实相关内容。本站不承担此类作品侵权行为的直接责任及连带责任。如若本网有任何内容侵犯您的权益,请及时联系我们,本站将会在24小时内处理完毕,E-mail:xinmeigg88@163.com

展开全文READ MORE
饼状图手机饼图
你好我为何杆不能连接手机啊杆怎么连接手机才可以用「你好我为何杆不能连接手机啊」 手机地图怎么标记多个点位 怎样在地图上显示多个地点蓝莓手机「手机地图怎么标记多个点位 怎样在地图上显示多个地点」