项目需要做一个android饼状图的效果 因为元素比较多 并且有些元素的百分比为0也需要显示出来,一开始考虑使用MPAndroidCharthttps://github.com/PhilJay/MPAndroidChart,毕竟点赞数量多 但是看了下效果 跟要求差别还是有点大,所以又找了个其他的项目参考PieChartViewhttps://github.com/luweibin3118/PieChartView, 这个项目 发现只能设置int类型的百分比 而且当条目过多的时候 会导致显示的文本覆盖重合之类的 所以改了两个地方

1.将int 类型改为float类型 百分比

2.将百分比显示由标注线下面移动到 content后面

下面贴下代码和效果

源代码可以去项目里面找  我只放下修改后的代码

import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PathMeasure;
import android.graphics.Point;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.LinearInterpolator;import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;
public class MyPieChartView extends View{private Paint mPaint;private Path mPath, drawLinePath = new Path();private PathMeasure mPathMeasure = new PathMeasure();private Canvas mCanvas;private int width, height;private RectF pieRectF, tempRectF;private int radius;private List<MyPieChartView.ItemType> itemTypeList, leftTypeList, rightTypeList;private List<Point> itemPoints;private int cell = 0;private float innerRadius = 0.0f;private float offRadius = 0, offLine;private int textAlpha;private Point firstPoint;private int backGroundColor = 0xffffffff;private int itemTextSize = 30, textPadding = 8;private int defaultStartAngle = -90;private float pieCell;private ValueAnimator animator;private long animDuration = 1000;private Point startPoint = new Point();private Point centerPoint = new Point();private Point endPoint = new Point();private Point tempPoint = new Point();public MyPieChartView(Context context) {super(context);init();}public MyPieChartView(Context context, AttributeSet attrs) {super(context, attrs);init();}private void init() {mPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG);mPath = new Path();pieRectF = new RectF();tempRectF = new RectF();itemTypeList = new ArrayList<>();leftTypeList = new ArrayList<>();rightTypeList = new ArrayList<>();itemPoints = new ArrayList<>();}@Overrideprotected void onAttachedToWindow() {super.onAttachedToWindow();startAnim();}@Overrideprotected void onDetachedFromWindow() {super.onDetachedFromWindow();if (animator != null) {animator.cancel();}}private void startAnim() {animator = ValueAnimator.ofFloat(0, 360f * 2);animator.setDuration(animDuration);animator.setInterpolator(new LinearInterpolator());animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {@Overridepublic void onAnimationUpdate(ValueAnimator animation) {float value = (float) animation.getAnimatedValue();if (value < 360f) {offRadius = value;offLine = 0;textAlpha = 0;} else if (value >= 360f) {offRadius = 360f;offLine = (value - 360f) / 360f;if (offLine > 0.5f) {textAlpha = (int) (255 * ((offLine - 0.5f) / 0.5f));if (textAlpha > 255) textAlpha = 255;} else {textAlpha = 0;}} else if (value == 360f * 2) {offRadius = 360f;offLine = 1.0f;textAlpha = 255;}postInvalidate();}});animator.start();}@Overrideprotected void onSizeChanged(int w, int h, int oldw, int oldh) {super.onSizeChanged(w, h, oldw, oldh);this.width = w;this.height = h;radius = Math.min(width, height) / 4;pieRectF.set(width / 2 - radius, height / 2 - radius, width / 2 + radius, height / 2 + radius);}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);try {mCanvas = canvas;drawPie();if (offRadius == 360f) {drawTitle();}} catch (Exception e) {e.printStackTrace();}}private void drawTitle() {resetPaint();float startRadius = defaultStartAngle;int count = rightTypeList.size();int h;if (count > 1) {h = (radius * 2) / (count - 1);} else {h = radius;}for (int i = 0; i < count; i++) {mPath.reset();MyPieChartView.ItemType itemType = rightTypeList.get(i);double angle = 2 * Math.PI * ((startRadius + itemType.radius / 2) / 360d);int x = (int) (width / 2 + radius * Math.cos(angle));int y = (int) (height / 2 + radius * Math.sin(angle));startPoint.set(x, y);centerPoint.set((int) (width / 2 + radius * 1.2f), height / 2 - radius + h * (i));endPoint.set((int) (width * 0.98f), centerPoint.y);mPath.moveTo(startPoint.x, startPoint.y);mPath.lineTo(centerPoint.x, centerPoint.y);mPath.lineTo(endPoint.x, endPoint.y);resetPaint();mPaint.setStrokeWidth(2);mPaint.setColor(itemType.color);mPaint.setStyle(Paint.Style.STROKE);mPathMeasure.setPath(mPath, false);drawLinePath.reset();mPathMeasure.getSegment(0, mPathMeasure.getLength() * offLine, drawLinePath, true);mCanvas.drawPath(drawLinePath, mPaint);startRadius += itemType.radius;if (textAlpha > 0) {mPaint.setTextSize(itemTextSize);mPaint.setStyle(Paint.Style.FILL);mPaint.setTextAlign(Paint.Align.CENTER);mPaint.setAlpha(textAlpha);mCanvas.drawText(itemType.type+itemType.getPercent(), centerPoint.x + (endPoint.x - centerPoint.x) / 2,centerPoint.y - textPadding, mPaint);mPaint.setTextSize(itemTextSize * 4 / 5);
//                mCanvas.drawText(itemType.getPercent(), centerPoint.x + (endPoint.x - centerPoint.x) / 2,
//                        centerPoint.y + (itemTextSize + textPadding) * 4 / 5, mPaint);  //itemType.getPercent()移动到itemType.type后面了}}count = leftTypeList.size();if (count > 1) {h = (radius * 2) / (count - 1);} else {h = radius;}for (int i = 0; i < count; i++) {mPath.reset();MyPieChartView.ItemType itemType = leftTypeList.get(i);double angle = 2 * Math.PI * ((startRadius + itemType.radius / 2) / 360d);int x = (int) (width / 2 + radius * Math.cos(angle));int y = (int) (height / 2 + radius * Math.sin(angle));startPoint.set(x, y);centerPoint.set((int) (width / 2 - radius * 1.2f), height / 2 - radius + h * (count - 1 - i));endPoint.set((int) (width * 0.02f), centerPoint.y);mPath.moveTo(startPoint.x, startPoint.y);mPath.lineTo(centerPoint.x, centerPoint.y);mPath.lineTo(endPoint.x, endPoint.y);resetPaint();mPaint.setStrokeWidth(2);mPaint.setColor(itemType.color);mPaint.setAntiAlias(true);mPaint.setDither(true);mPaint.setStyle(Paint.Style.STROKE);mPathMeasure.setPath(mPath, false);drawLinePath.reset();mPathMeasure.getSegment(0, mPathMeasure.getLength() * offLine, drawLinePath, true);mCanvas.drawPath(drawLinePath, mPaint);startRadius += itemType.radius;if (textAlpha > 0) {mPaint.setTextSize(itemTextSize);mPaint.setStyle(Paint.Style.FILL);mPaint.setTextAlign(Paint.Align.CENTER);mPaint.setAlpha(textAlpha);mCanvas.drawText(itemType.type+itemType.getPercent(), centerPoint.x + (endPoint.x - centerPoint.x) / 2,centerPoint.y - textPadding, mPaint);mPaint.setTextSize(itemTextSize * 4 / 5);
//                mCanvas.drawText(itemType.getPercent(), centerPoint.x + (endPoint.x - centerPoint.x) / 2,
//                        centerPoint.y + (itemTextSize + textPadding) * 4 / 5, mPaint);}}if (textAlpha == 1f) {itemTypeList.clear();leftTypeList.clear();rightTypeList.clear();itemPoints.clear();}}private void drawPie() {if (mCanvas == null) {return;}mCanvas.drawColor(backGroundColor);mPaint.setStyle(Paint.Style.FILL);float sum = 0;for (MyPieChartView.ItemType itemType : itemTypeList) {sum += itemType.widget;}float a = 360f / sum;float startRadius = defaultStartAngle;float sumRadius = 0;leftTypeList.clear();rightTypeList.clear();itemPoints.clear();for (MyPieChartView.ItemType itemType : itemTypeList) {itemType.radius = itemType.widget * a;double al = 2 * Math.PI * ((startRadius + 90) / 360d);tempPoint.set((int) (width / 2 + radius * Math.sin(al)),(int) (height / 2 - radius * Math.cos(al)));if (cell > 0) {if (startRadius == defaultStartAngle) {firstPoint = tempPoint;}}double angle = 2 * Math.PI * ((startRadius + itemType.radius / 2) / 360d);double sin = -Math.sin(angle);double cos = -Math.cos(angle);if (cos > 0) {leftTypeList.add(itemType);} else {rightTypeList.add(itemType);}sumRadius += Math.abs(itemType.radius);mPaint.setStyle(Paint.Style.FILL);mPaint.setColor(itemType.color);if (pieCell > 0) {if (sumRadius <= offRadius) {tempRectF.set(pieRectF.left - (float) (pieCell * cos), pieRectF.top - (float) (pieCell * sin),pieRectF.right - (float) (pieCell * cos), pieRectF.bottom - (float) (pieCell * sin));mCanvas.drawArc(tempRectF, startRadius, itemType.radius, true, mPaint);} else {mCanvas.drawArc(tempRectF, startRadius, itemType.radius - (Math.abs(offRadius - sumRadius)), true, mPaint);break;}} else {if (sumRadius <= offRadius) {mCanvas.drawArc(pieRectF, startRadius, itemType.radius, true, mPaint);} else {mCanvas.drawArc(pieRectF, startRadius, itemType.radius - (Math.abs(offRadius - sumRadius)), true, mPaint);break;}}startRadius += itemType.radius;if (cell > 0 && pieCell == 0) {mPaint.setColor(backGroundColor);mPaint.setStrokeWidth(cell);mCanvas.drawLine(getWidth() / 2, getHeight() / 2, tempPoint.x, tempPoint.y, mPaint);}}if (cell > 0 && firstPoint != null && pieCell == 0) {mPaint.setColor(backGroundColor);mPaint.setStrokeWidth(cell);mCanvas.drawLine(getWidth() / 2, getHeight() / 2, firstPoint.x, firstPoint.y, mPaint);}mPaint.setStyle(Paint.Style.FILL);mPaint.setColor(backGroundColor);if (innerRadius > 0 && pieCell == 0) {mCanvas.drawCircle(width / 2, height / 2, radius * innerRadius, mPaint);}}public void resetPaint() {mPaint.reset();mPaint.setAntiAlias(true);mPaint.setDither(true);mPaint.setAlpha(255);}/*** 添加一条分类数据** @param itemType*/public void addItemType(MyPieChartView.ItemType itemType) {if (itemTypeList != null) {itemTypeList.add(itemType);}}/*** 设置每条图之间的间歇大小** @param cell*/public void setCell(int cell) {this.cell = cell;}/*** 设置内部圆的半径比例,eg:0.5f** @param innerRadius*/public void setInnerRadius(float innerRadius) {if (innerRadius > 1.0f) {innerRadius = 1.0f;} else if (innerRadius < 0) {innerRadius = 0;}this.innerRadius = innerRadius;}/*** 设置背景颜色** @param backGroundColor*/public void setBackGroundColor(int backGroundColor) {this.backGroundColor = backGroundColor;}/*** 设置每条字体大小** @param itemTextSize*/public void setItemTextSize(int itemTextSize) {this.itemTextSize = itemTextSize;}/*** 设置字体距离横线的padding值** @param textPadding*/public void setTextPadding(int textPadding) {this.textPadding = textPadding;}/*** 设置动画时间** @param animDuration*/public void setAnimDuration(long animDuration) {this.animDuration = animDuration;}/*** 代替方法{@link #setCell(int)}** @param pieCell*/@Deprecatedpublic void setPieCell(int pieCell) {this.cell = pieCell;}public static class ItemType {private static final DecimalFormat df = new DecimalFormat("0.0%");String type;float widget;int color;float radius;public ItemType(String type, float widget, int color) {this.type = type;this.widget = widget;this.color = color;}public String getPercent() {return df.format(radius / 360f);}}
}

布局文件:

   <com.runjiang.cityplatform.widget.MyPieChartViewandroid:id="@+id/piechart"android:layout_width="match_parent"android:layout_height="300dp"/>

使用方法很简单:

pieChartView.addItemType(new PieChartView.ItemType("小米", 13, 0xff8B5A00));

Android饼状图相关推荐

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

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

  2. android饼状图简书,Charts-饼状图

    上篇文章已经讲述了折线图的用法这边文章主要来谈饼状图. 其实Charts难的部分主要在于配置,所以同样主要说说他的配置. pieGraphView.setExtraOffsets(left: 10, ...

  3. android 中空饼图控件,android饼状图内是空心的怎么做

    满意答案 先定义一个GraphicalView GraphicalView graphicalView; 然后,从chartfactory获取 graphicalView=ChartFactory.g ...

  4. android带动画的饼图,Android部分源码资源共享(视屏转GIF图片工具、仿抖音、仿朋友圈、仿红包、饼状图、引导图,图灵源码等)...

    视屏转为gif图片工具: 下载地址:CSDN 下载 1.封装了各项工具类,例如,日志,打印,缓存等,可直接使用项目 百度网盘:下载    提取码:fq07 2.Android高仿抖音 1.项目 的bu ...

  5. android 第三方扇形图,Android扇形图(饼状图)

    关于Android的图形控件,市场上是有很多的开源库的 我个人用的比较多的就是:MPAndroidChart,个人感觉挺好用的,但是有写时候,满足不了需求,就需要自己去写了. 先看看我们的效果图: T ...

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

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

  7. android 最简单的饼状图

    录制的gif图有点渣,但是实际效果还是可以的. 因为项目需要绘制饼状图,就很简单的饼状图带一个选中的效果,本来也想使用MPAndroidChart这个库的,但是觉得就实现一个效果引用整个库,对于一个有 ...

  8. Android自定义饼状图

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

  9. Android部分源码资源共享(视屏转GIF图片工具、仿抖音、仿朋友圈、仿红包、饼状图、引导图,图灵源码等)

    视屏转为gif图片工具: 下载地址:CSDN 下载 1.封装了各项工具类,例如,日志,打印,缓存等,可直接使用项目 百度网盘:下载     提取码:fq07 2.Android高仿抖音 1.项目 的b ...

最新文章

  1. JFinal 源码build脚本
  2. sql盲注特点_SQL注入第二章——access,mssql,oracle
  3. YTU 2917: Shape系列-3
  4. mysql insert报错_mysql数据库使用insert语句插入中文数据报错
  5. Web应用安全————多点登录互斥
  6. Python菜鸟之python入门
  7. appinventor如何做个游戏_单亮:游戏的重要性
  8. ajaxSubmit
  9. 《Arduino奇妙之旅:智能车趣味制作天龙八步》一1.6 A计划
  10. 在matlab中饼图种类,Excel2016中饼图的常见类型及绘制方法
  11. 关于应用RestHighLevelClient操作ElasticSearch出现“远程主机强迫关闭一个现有连接”的问题探究
  12. vue-cli4 + cordova扫描二维码
  13. 【区块链108将】流量之王的48小时生死转折
  14. Android应用开发接入讯飞语音合成
  15. Java_7.1 ArrayList应用点名器
  16. MYSQL中where条件后写上1=1 是什么意思?
  17. pandas常用方法
  18. 矩阵指数(The Exponential of a Matrix)
  19. 英国脱欧对全球科技业产生哪些影响?
  20. 给linux文件夹设置权限

热门文章

  1. 单片机C51数据类型和存储器类型
  2. git进行push报错: RPC failed; HTTP 403 curl 22 The requested URL returned error: 403 Forbidden
  3. 排序算法汇总--冒泡,插入,归并,快速,堆,计数,基数,桶排序
  4. RabbitMQ实现消息的延迟推送或延迟发送
  5. python3指定目录所有excel_Python——合并指定文件夹下的所有excel文件
  6. 参加计算机能力培训计划,计算机技能培训计划Word版
  7. Elsevier论文草稿在排版时如何添加行号?(单栏排版,双栏排版)
  8. Mac删除残留图标命令
  9. 2021-2027中国半导体掩膜版市场现状及未来发展趋势
  10. java实现第七届蓝桥杯碱基