为了加强对自定义 View 的认知以及开发能力,我计划这段时间陆续来完成几个难度从易到难的自定义 View,并简单的写几篇博客来进行介绍,所有的代码也都会开源,也希望读者能给个 star 哈 GitHub 地址:github.com/leavesC/Cus… 也可以下载 Apk 来体验下:www.pgyer.com/CustomView

先看下效果图:

一、抽象概念

假设每个扇形所代表的数据的数据都是 float 类型的,这些数据需要由外部传入给 View,View 内部再来根据数据总量来计算各项数据的占比,各个扇形的角度就是以此来决定

为了简单起见,各个扇形的颜色值由 View 内部来决定,外部只需传入数据大小即可,将此概念抽象为 PercentageModel

/*** 作者:leavesC* 时间:2019/4/10 14:28* 描述:*/
public class PercentageModel {private float value;private float angle;private int color;}
复制代码

二、确定宽高、初始化画笔

    public PercentageView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);initPaint();}private void initPaint() {paint = new Paint();paint.setStyle(Paint.Style.FILL);paint.setAntiAlias(true);paint.setDither(true);}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {int defaultSize = dp2px(DEFAULT_SIZE);int width = getSize(widthMeasureSpec, defaultSize);int height = getSize(heightMeasureSpec, defaultSize);width = height = Math.min(width, height);setMeasuredDimension(width, height);Log.e(TAG, "onMeasure");}
复制代码

三、传入数据源

外部传入的数据只包含数据量 value 这个参数而已,因此还需要在 View 内部计算数据占比,并为数据项按照顺序赋予颜色值。为了避免精度损失,还需要在最后判断占比总和是否就是 360 度,不是的话则需要将损失值赋予最后一项数据

private List<PercentageModel> percentageModelList;private static final int[] COLORS = {0xff2f7e76, 0xff1ff749, 0xfff42872, 0xff4643f4, 0xe51581da, 0xff8527e4, 0xfff1b00d, 0xff26020f};public void setData(List<PercentageModel> percentageModelList) {this.percentageModelList = percentageModelList;initData(percentageModelList);invalidate();}private void initData(List<PercentageModel> percentageModelList) {if (percentageModelList == null || percentageModelList.size() == 0) {return;}float sumValue = 0;for (int i = 0; i < percentageModelList.size(); i++) {PercentageModel percentageModel = percentageModelList.get(i);sumValue += percentageModel.getValue();percentageModel.setColor(COLORS[i % COLORS.length]);}float sumAngle = 0;for (PercentageModel percentageModel : percentageModelList) {float per = percentageModel.getValue() / sumValue;percentageModel.setAngle(per * 360);sumAngle += percentageModel.getAngle();}//计算百分比时可能有一些精度损失,此处需要判断是否需要把差值补回来if (sumAngle < 360) {for (PercentageModel percentageModel : percentageModelList) {if (percentageModel.getAngle() != 0) {percentageModel.setAngle(360 - sumAngle + percentageModel.getAngle());break;}}}}
复制代码

四、绘制

    private RectF rect = new RectF();@Overrideprotected void onDraw(Canvas canvas) {if (percentageModelList == null || percentageModelList.size() == 0) {return;}float currentStartAngle = startAngle;canvas.translate(getWidth() / 2, getHeight() / 2);float r = (float) (Math.min(getWidth(), getHeight()) / 2 * 0.95);rect.left = -r;rect.top = -r;rect.right = r;rect.bottom = r;for (PercentageModel percentageModel : percentageModelList) {paint.setColor(percentageModel.getColor());canvas.drawArc(rect, currentStartAngle, percentageModel.getAngle(), true, paint);currentStartAngle += percentageModel.getAngle();}}
复制代码

通过全局变量 startAngle 来指定第一个扇形的起始角度,并将其 set 方法开放给外部,并在 set 方法内主动刷新 View

    private float startAngle;public void setStartAngle(float startAngle) {this.startAngle = startAngle;invalidate();}
复制代码

转载于:https://juejin.im/post/5ccd772be51d456e537ef3b1

自定义View合辑(2)-饼状图相关推荐

  1. kotllin自定义view_GitHub - wangshuaialex/Kotlin-CustomView: Kotlin实现的自定义View(仪表盘、饼状图、圆形头像)...

    #自定义View-Kotlin版 本文的目的有两个: 大多数时候,自定义View并不会被用到,但一旦用到,通常都是很炫酷的效果.App的开发本身并不酷,让它们变酷的是设计师们的想象力与创造力.对于开发 ...

  2. 自定义View合辑(8)-跳跃的小球(贝塞尔曲线)

    为了加强对自定义 View 的认知以及开发能力,我计划这段时间陆续来完成几个难度从易到难的自定义 View,并简单的写几篇博客来进行介绍,所有的代码也都会开源,也希望读者能给个 star 哈 GitH ...

  3. Flutter 自定义View之 饼状图

    版权声明:本文为博主原创文章,转载请注明出处! 今天跟大家分享的是用Flutter来实现的自定义饼状图,下面来看看效果! 通过点击左右两侧的按钮,可以实现扇形切换,被选中的扇形有个放大的效果,中间的百 ...

  4. android 自定义饼图半径不定,【Android】仿支付宝账单统计饼状图的自定义view

    仿支付宝统计饼状图的自定义view,如下图: 项目地址:https://github.com/bigeyechou/CustomViewCollection 目录:customviewcollecti ...

  5. android饼状图简书,自定义 view 练手 - 简单的饼状图

    今天咱们来一个例子练练手,饼状图这样的图表算是最好的了,复杂的话可以很复杂, 采用 surfaceview + 动画 可以使用很优秀的观感体验:简单的话可以很简单,仅仅画出图来就行,不用考虑动画啥的 ...

  6. android自定义View: 饼状图绘制(四)

    本系列自定义View全部采用kt 系统mac android studio: 4.1.3 kotlin version1.5.0 gradle: gradle-6.5-bin.zip 本篇效果: 画矩 ...

  7. Android自定义View之扇形饼状图

    前言:继上次写了自定义圆形进度条后,今天给大家带来自定义扇形饼状图.先上效果图: 是不是很炫?看上去还有点立体感.下面带大家一起来瞧一瞧吧. 一.定义成员变量,重写构造方法 看着这个效果图,我们可以想 ...

  8. Android自定义饼状图

    1.啥都别说,先上效果图. 2.这效果是平时真实项目开发可能用到的.我也是看到Android交流群里有人要这种效果,于是开始动手写一写. 3.分析:这个自定义View效果 的实现大概分为几步 3.1. ...

  9. 安卓饼状图设置软件_安卓(Android)开发之自定义饼状图

    先来看看效果图 先分析饼状图的构成,非常明显,饼状图就是一个又一个的扇形构成的,每个扇形都有不同的颜色,对应的有名字,数据和百分比. 经以上信息可以得出饼状图的最基本数据应包括:名字 数据值 百分比 ...

  10. iOS 中饼状图的自定义绘制

    前几天有一个需求是制作一个统计工资的饼状图,但是和一般的饼状图不同的是要求该饼状图中心需要有两条文字,功能需求就是这样,先上一张效果图: 因为咱们的饼状图本身只是一个View ,在调用的时候一定是在一 ...

最新文章

  1. 【牛客挑战赛】我是 A 题
  2. Groovy 之 Closure
  3. 用数据可视化解读:为何2亿国人爱钓鱼
  4. 如何运行一段python代码_Python退出时强制运行一段代码如何实现 Python退出时强制运行一段代码实现方法...
  5. linux集群搭建coolrainbow,Rainbow°110408_教程▍KBFS听歌学韩语—So Cool[Rainbow]
  6. 存储过程打印超过8000的VARCHAR字符的问题
  7. js获取节点的DOM操作
  8. 【蓝桥杯单片机】矩阵键盘和独立键盘新解(更稳定更高复用性)
  9. 【算法】删去k个数字后的最小值
  10. MATLAB切比雪夫带通滤波器
  11. Anylogic 创建一个简单的人口演变模型
  12. 详解ICT及其业务领域范围
  13. 威纶通与三菱PLC条码枪解码程序 本程序是威纶通触摸屏USB接头直接插条形码扫码枪
  14. ThinkPHP V5.0.5漏洞_谷歌浏览器 v80.0.3987.100 正式版——墨涩网
  15. bandzip屏蔽广告
  16. 黑客攻防日记---刘欣
  17. 做不到想做的,真难受~
  18. java中的Int范围
  19. 微信小程序海报功能(canvas)- - -附效果图
  20. M1芯片的mac下的Xcode12以上版本编译报错 this target. for architecture arm64等问题解决方案

热门文章

  1. 三种找回丢失iPhone的方法,来自苹果手机找回网
  2. as3实现(可以操纵的)真正的由惯性导致的漂移
  3. 用firefox保存网页
  4. Go语言的线程模型-Goroutine机制
  5. Machine Learning——Homework4
  6. matlab改变遥感图像的存储格式
  7. phpstorm2017破解方法
  8. 计算机应用技术基础考试分值,计算机一级考试内容包括哪些 试题分值上是如何分布的...
  9. php中fread用法,php fread函数与fread函数用法
  10. 实习成长之路:MySQL十:怎么给字符串字段加索引?