android 扇形统计图

先看看效果:

看上去如果觉得还行就继续往下看吧!

自定义view

定义成员变量

private int mheight, mwidth;//宽高

private paint mpaint;//扇形的画笔

private paint mtextpaint;//画文字的画笔

private int centerx, centery;//中心坐标

//"其他"的value

//扇形图分成太多快 所以要合并一部分为其他 即图中灰色部分

private double rest;

private int maxnum = 5;//扇形图的最大块数 超过的item就合并到其他

string others = "其他";//“其他”块要显示的文字

double total;//数据的总和

double[] datas;//数据集

string[] texts;//每个数据对应的文字集

//颜色 默认的颜色

private int[] mcolors = {

color.parsecolor("#ff4081"), color.parsecolor("#ffc0cb"),

color.parsecolor("#00ff00"), color.parsecolor("#0066ff"), color.parsecolor("#ffee00")

};

private int mtextsize;//文字大小 单位:像素

private int radius = 1000;//半径 在画图时初始化

测量宽高

@override

protected void onmeasure(int widthmeasurespec, int heightmeasurespec) {

super.onmeasure(widthmeasurespec, heightmeasurespec);

//获取宽高 不要设置wrap_content

mheight = measurespec.getsize(heightmeasurespec);

mwidth = measurespec.getsize(widthmeasurespec);

}

画图

@override

protected void ondraw(canvas canvas) {

super.ondraw(canvas);

//无数据 直接返回

if (datas == null || datas.length == 0) return;

centerx = (getright() - getleft()) / 2;

centery = (getbottom() - gettop()) / 2;

int min = mheight > mwidth ? mwidth : mheight;

if (radius > min / 2) {

radius = (int) ((min - getpaddingtop() - getpaddingbottom()) / 3.5);

}

//画各个扇形

drawcircle(canvas);

//画线与文字

drawlineandtext(canvas);

}

画扇形

一个圆形统计图是由许多个扇形组成的,我们根据数据计算出每个扇形的角度即可。注意,画弧度的时候,角度是顺时针变大的!即与我们平时的坐标是反过来的

//画扇形

private void drawcircle(canvas canvas) {

int centerx =( getright() - getleft() )/2;//中点

int centery = ( getbottom() - gettop()) /2;

rectf rect = new rectf((float) (centerx - radius), centery-radius,

centerx+radius,centery+radius);//圆形区域

int start = 0;//扇形开始的角度

for (int i = 0; i < (maxnum

float angles = (float) ((datas[i] * 1.0f /total) * 360);//计算扇形的角度

mpaint.setcolor(mcolors[i%mcolors.length]);//颜色

canvas.drawarc(rect,start,angles,true,mpaint);//画扇形

start += angles;//下一个扇形开始的角度

}

//画"其他"部分 即图中灰色的部分

rest =0;//保存其他部分的value

for(int i=maxnum;i

rest+=datas[i];

}

float angles = (float) 360 - start;//角度

mpaint.setcolor(color.gray);

canvas.drawarc(rect,start,angles,true,mpaint);

}

画线条和文字

主要是计算各个点的坐标很烦

这里我画出一个图 大家把代码和图对照理解一下

//画线与文字

private void drawlineandtext(canvas canvas) {

int start = 0;

//平移画布到中心 所以下面的坐标是从中点开始算起的

canvas.translate(centerx, centery);

mpaint.setstrokewidth(4);//线条宽度

//如果数据集过大 那么要合并到其他

for (int i = 0; i < (maxnum < datas.length ? maxnum : datas.length); i++) {

float angles = (float) ((datas[i] * 1.0f / total) * 360);

//画线条和文字

drawline(canvas, start, angles, texts[i], mcolors[i % mcolors.length]);

start += angles;

}

//画其他部分的线条和文字

if (start < 360)//如果start小于360 说明有其他部分

drawline(canvas, start, 360 - start, others, color.gray);

}

private void drawline(canvas canvas, int start, float angles, string text, int color) {

mpaint.setcolor(color);

float stopx, stopy;

stopx = (float) ((radius + 40) * math.cos((2 * start + angles) / 2 * math.pi / 180));

stopy = (float) ((radius + 40) * math.sin((2 * start + angles) / 2 * math.pi / 180));

canvas.drawline((float) ((radius - 20) * math.cos((2 * start + angles) / 2 * math.pi / 180)),

(float) ((radius - 20) * math.sin((2 * start + angles) / 2 * math.pi / 180)),

stopx, stopy, mpaint

);

//画横线

int dx;//判断横线是画在左边还是右边

int endx;

if (stopx > 0) {

endx = (centerx - getpaddingright() - 20);

} else {

endx = (-centerx + getpaddingleft() + 20);

}

//画横线

canvas.drawline(stopx, stopy,

endx, stopy, mpaint

);

dx = (int) (endx - stopx);

//测量文字大小

rect rect = new rect();

mtextpaint.gettextbounds(text, 0, text.length(), rect);

int w = rect.width();

int h = rect.height();

int offset = 20;//文字在横线的偏移量

//画文字 文字的y坐标值的是文字底部的y坐标

canvas.drawtext(text, 0, text.length(), dx > 0 ? stopx + offset : stopx - w - offset, stopy + h, mtextpaint);

//测量百分比大小

string percentage = angles / 3.60 + "";

percentage = percentage.substring(0, percentage.length() > 4 ? 4 : percentage.length()) + "%";

mtextpaint.gettextbounds(percentage, 0, percentage.length(), rect);

w = rect.width() - 10;

//画百分比

canvas.drawtext(percentage, 0, percentage.length(), dx > 0 ? stopx + offset : stopx - w - offset, stopy - 5, mtextpaint);

}

这样我们就已经完成了绘制的工作了,接下来就是绑定数据啦!

大家只要把datas和texts填充好数据就可以啦,最好调用一下invalidate()方法请求重绘(如果已经绘制了)。

我使用了一个内部抽象类来实现数据绑定的:

public abstract class arcviewadapter {

public void setdata(list list) {

datas = new double[list.size()];

texts = new string[list.size()];

for (int i = 0; i < list.size(); i++) {

total += getvalue(list.get(i));

datas[i] = getvalue(list.get(i));

texts[i] = gettext(list.get(i));

}

invalidate();//请求重绘

}

//通过传来的数据集的某个元素 得到具体的数字

public abstract double getvalue(t t);

//通过传来的数据集的某个元素 得到具体的描述

public abstract string gettext(t t);

}

在布局文件里面引用这个arcview,然后在mainactivity中绑定数据:

arcview arcview = (arcview) findviewbyid(r.id.arc);

list times = new arraylist<>();

for (int i = 6; i > 0; i--) {

times t = new times();//这个类就只有两个变量

t.hour = i;

t.text = "number"+i;

times.add(t);

}

//初始化适配器

arcview.arcviewadapter myadapter = arcview.new arcviewadapter(){

@override

public double getvalue(times times) {

return times.hour;

}

@override

public string gettext(times times) {

return times.text;

}

};

myadapter.setdata(times);//绑定数据

大家可以设置各种setter以便在activity中调用,来提高arcview的灵活性,比如设置颜色、半径、最大块数等等。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持萬仟网。

android 扇形统计动画,Android自定义View——扇形统计图的实现代码相关推荐

  1. Android 雪花飘落动画效果 自定义View

    在码农的世界里,优美的应用体验,来源于程序员对细节的处理以及自我要求的境界,年轻人也是忙忙碌碌的码农中一员,每天.每周,都会留下一些脚印,就是这些创作的内容,有一种执着,就是不知为什么,如果你迷茫,不 ...

  2. android录音波浪动画_Android自定义View实现波浪动画

    本文实例为大家分享了Android自定义View实现波浪动画的具体代码,供大家参考,具体内容如下 效果演示 代码调用与实现效果 xml中调用 android:layout_width="ma ...

  3. android录音波浪动画_Android 自定义 view 实现波浪动画进度条

    最近在做项目时需要实现这样一种动画,类似于波浪形的进度动画,粗略的看了一下,发现好像类似于正余弦曲线实现的,但是Android 没有相关的API,所以需要我们动手画出来,所以现在在此记录一下学习过程, ...

  4. Android属性动画与自定义View——实现vivo x6更新系统的动画效果

    晚上好,现在是凌晨两点半,然后我还在写代码.电脑里播放着<凌晨两点半>,晚上写代码,脑子更清醒,思路更清晰. 今天聊聊属性动画和自定义View搭配使用,前面都讲到自定义View和属性动画, ...

  5. Android 气泡动画(自定义View类)

    Android 气泡动画(自定义View类) 一.前言 二.代码 1. 随机移动的气泡 2.热水气泡 一.前言 最近有需求制作一个水壶的气泡动画,首先在网上查找了一番,找到了一个文章. https:/ ...

  6. Android软件开发之盘点自定义View界面大合集(二)

    Android软件开发之盘点自定义View界面大合集(二) - 雨松MOMO的程序世界 - 51CTO技术博客 雨松MOMO带大家盘点Android 中的自定义View界面的绘制 今天我用自己写的一个 ...

  7. Carson带你学Android:源码解析自定义View Draw过程

    前言 自定义View是Android开发者必须了解的基础 网上有大量关于自定义View原理的文章,但存在一些问题:内容不全.思路不清晰.无源码分析.简单问题复杂化 等 今天,我将全面总结自定义View ...

  8. Android中实现Bitmap在自定义View中的放大与拖动

    一基本实现思路: 基于View类实现自定义View –MyImageView类.在使用View的Activity类中完成OnTouchListener接口,实现对MotionEvent事件的监听与处理 ...

  9. Android 自定义 圆环,Android自定义view实现圆环效果实例代码

    先上效果图,如果大家感觉不错,请参考实现代码. 重要的是如何实现自定义的view效果 (1)创建类,继承view,重写onDraw和onMesure方法 public class CirclePerc ...

  10. android 仿360浮动,Android仿360悬浮小球自定义view实现示例

    Android仿360悬浮小球自定义view实现示例 效果图如下: 实现当前这种类似的效果 和360小球 悬浮桌面差不错类似.这种效果是如何实现的呢.废话不多说 ,直接上代码. 1.新建工程,添加悬浮 ...

最新文章

  1. Centos7 安装maven3.5.0和git
  2. 二叉树的非递归遍历(c/c++)
  3. [云炬创业学笔记]第一章创业是什么测试10
  4. vue 固定div 滚动_vue移动端 导航吸顶(固定定位)页面滚动出现抖动
  5. 利用设计模式替代项目中的if else(转)
  6. 基于.NET Core的简单,跨平台,模块化的电子商务系统-SimplCommerce
  7. InfluxDB 简介、安装和简单使用
  8. dataframe 控对象_iOS知识 - 常用小技巧大杂烩
  9. Kafka产品迭代计划(RoadMap)
  10. 远程办公一晃一天,环境搭建履步维艰
  11. ajax瀑布流 dede,dedecms加载更多,无限下拉瀑布流插件
  12. Docker系列教程15-Docker容器网络
  13. python统计图像灰度直方图_python 对一幅灰度图像进行直方图均衡化
  14. (三)MFC学习之动画
  15. C++ 解决大数运算(大数加法,大数幂运算,大数求余)
  16. Huffman实现对26个英文字母的编码
  17. *TEST 11 for NOIP 再次爆炸 (100-300)-----(( ! ))
  18. Java项目使用jib打包docker镜像的简单记录
  19. 【统计年鉴下载】夏泽网
  20. html如何设置网页的背景图片,使放大或缩小浏览器时,页面排版和背景可以随浏览器放大缩小而排版不会改变,

热门文章

  1. 设置jupyter notebook软件的字体样式
  2. Linux内核源码如何学习?
  3. 更换pycharm主题
  4. SQL Server 2016下载及安装教程
  5. Activiti 工作流表单设计及开发
  6. 程序员的电脑文件管理技巧
  7. 测试工具平台介绍之MeterSphere
  8. oracle创建用户
  9. java excel 2007兼容包_Microsoft Office 2007兼容包
  10. Android音视频架构-学习路线规划