ITPub博客

首页 > IT职业 > IT职场 > Android动态绘制饼状图

Android动态绘制饼状图

IT职场 作者:sinlong 时间:2021-09-09 09:10:11 0 删除 编辑

作者:_xiangpan,原文地址

项目里面的需求,当时搜索到MPAndroidChart库,可以实现,但是只是一个需求就引用偌大的一个库,感觉不太爽,打算自己自定义一个。 参考+实践

一、惯例先上效果图

图片描述
效果图
图片描述
更新图

二、GitHub

代码地址,欢迎指正https://github.com/MNXP/XPPieChart

三、思路

1、空心图(一个大圆中心绘制一个小圆)
2、根据数据算出所占的角度
3、根据动画获取当前绘制的角度
4、根据当前角度获取Paint使用的颜色
5、动态绘制即将绘制的 和 绘制已经绘制的部分(最重要)

四、实现

1、空心图(一个大圆中心绘制一个小圆)初始化数据

paint = new Paint();
  paint.setAntiAlias(true);
  paint.setStyle(Paint.Style.FILL_AND_STROKE);

  screenW = DensityUtils.getScreenWidth(context);

  int width = DensityUtils.dip2px(context, 15);//圆环宽度
  int widthXY = DensityUtils.dip2px(context, 10);//微调距离

  int pieCenterX = screenW / 2;//饼状图中心X
  int pieCenterY = screenW / 3;//饼状图中心Y
  int pieRadius = screenW / 4;// 大圆半径

  //整个饼状图rect
  pieOval = new RectF();
  pieOval.left = pieCenterX - pieRadius;
  pieOval.top = pieCenterY - pieRadius + widthXY;
  pieOval.right = pieCenterX + pieRadius;
  pieOval.bottom = pieCenterY + pieRadius + widthXY;

  //里面的空白rect
  pieOvalIn = new RectF();
  pieOvalIn.left = pieOval.left + width;
  pieOvalIn.top = pieOval.top + width;
  pieOvalIn.right = pieOval.right - width;
  pieOvalIn.bottom = pieOval.bottom - width;

  //里面的空白画笔
  piePaintIn = new Paint();
  piePaintIn.setAntiAlias(true);
  piePaintIn.setStyle(Paint.Style.FILL);
  piePaintIn.setColor(Color.parseColor("#f4f4f4"));

2、根据数据算出所占的角度

使用递归保证cakeValues的值的总和必为100,然后根据值求出角度

  private void settleCakeValues(int i) {
       float sum = getSum(cakeValues, i);
       CakeValue value = cakeValues.get(i);
       if (sum 

3、根据动画获取当前绘制的角度

curAngle就是当前绘制的角度,drawArc()就是绘制的方法
cakeValueAnimator.addUpdateListener(new AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                float mAngle = obj2Float(animation.getAnimatedValue("angle"));
                curAngle = mAngle;
                drawArc();
            }
        });

4、根据当前角度获取Paint使用的颜色

根据当前的角度,计算当前是第几个item,通过

paint.setColor(Color.parseColor(cakeValues.get(colorIndex).getColors()));

来设置paint的颜色

private int getCurItem(float curAngle) {
        int res = 0;
        for (int i = 0; i 

5、动态绘制即将绘制的 和 绘制已经绘制的部分

最重要的一步,我的需求是4类,用不同的颜色
绘制当前颜色的扇形,curStartAngle扇形的起始位置,curSweepAngle扇形的终止位置

  paint.setColor(Color.parseColor(cakeValues.get(colorIndex).getColors()));
  float curStartAngle = 0;
  float curSweepAngle = curAngle;
  if (curItem > 0) {
      curStartAngle = itemFrame[curItem - 1] * ANGLE_NUM;
      curSweepAngle = curAngle - (itemFrame[curItem - 1] * ANGLE_NUM);
   }
   canvas.drawArc(pieOval, curStartAngle, curSweepAngle, true, paint);

绘制已经绘制的扇形。根据curItem判断绘制过得扇形

for (int i = 0; i 

绘制中心的圆

 canvas.drawArc(pieOvalIn, 0, 360, true, piePaintIn);

6、特别注意

isFirst判断是够是第一次绘制(绘制完成后,home键进入后台,再次进入,不需要动态绘制)

 @Override
    protected void onDraw(Canvas canvas) {
        if (isFirst && isDrawByAnim) {
            drawCakeByAnim();
        }
        isFirst = false;
    }

isDrawByAnim判断是否需要动画绘制
drawCake()为静态绘制饼状图

public void surfaceCreated(SurfaceHolder holder) {
    if (!isFirst||!isDrawByAnim)
          drawCake();
}
更新

增加立体效果,提取配置参数

//是否动画
        //是否立体
        //动画时间
        //默认颜色

        //圆环宽度
        //立体宽度
        //微调宽度
    
xml中使用

以上就是简单的实现动态绘制饼状图,待完善,以后会更新。如有建议和意见,请及时沟通。

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/3156/viewspace-2799765/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2019-08-30

  • 博文量
    0
  • 访问量
    685