Android开发中,自定义饼图PieChartView

本文介绍如何在Android开发中自定义饼图,以解决第三方库无法满足需求的问题。通过将大圆分为左右两部分绘制,避免了数据过多导致的延长线和说明文字重叠。文章详细讲解了绘制步骤,并提供了XML布局和类中调用的示例,源代码后续会上传供下载修改。
摘要由CSDN通过智能技术生成

在我们开发中我们经常会用到饼图,这个时候我们可以选中第三方库,进行修改定义我们需要的饼图,但是在实际开发中,我们三方库有时候并不能满足我们的需求,这个时候就需要我们进行自定绘制饼图,下面主要讲解的就是自定义饼图,主要解决了,由于饼图的分数太多而造成绘制的延长线以及说明挤到一块:

本篇主要将绘制大圆形分成左右两份,然后根据左右不同的数据进行绘制,从而避免了重叠的问题:

第一步:绘制饼图:

 private void drawPie() {
        if (mCanvas == null) {
            return;
        }
        mCanvas.drawColor(backGroundColor);
        mPaint.setStyle(Paint.Style.FILL);
        float sum = 0;
        for (ItemType itemType : itemTypeList) {
            sum += itemType.widget;
        }
        float a = 360f / sum;
        float startRadius = defaultStartAngle;
        float sumRadius = 0;
        leftTypeList.clear();
        rightTypeList.clear();
        itemPoints.clear();
        for (ItemType itemType : itemTypeList) {
            Log.e("timo-00", itemType.sleeptime);
            itemType.radius = itemType.widget * a;
            double al = 2 * Math.PI * ((startRadius + 90) / 360d);
            Point point = new Point((int) (width / 2 + radius * Math.sin(al)),
                    (int) (height / 2 - radius * Math.cos(al)));
            if (cell > 0) {
                if (startRadius == defaultStartAngle) {
                    firstPoint = point;
                }
            }

            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);
            }
//            Log.e("timo-00","sin:"+sin+"  "+"cos:"+cos);
            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 {
                /**
                 * 1.PorterDuff.Mode.CLEAR
                 * 所绘制不会提交到画布上。
                 * 2.PorterDuff.Mode.SRC
                 * 显示上层绘制图片
                 * 3.PorterDuff.Mode.DST
                 * 显示下层绘制图片
                 * 4.PorterDuff.Mode.SRC_OVER
                 * 正常绘制显示,上下层绘制叠盖。
                 * 5.PorterDuff.Mode.DST_OVER
                 * 上下层都显示。下层居上显示。
                 * 6.PorterDuff.Mode.SRC_IN
                 * 取两层绘制交集。显示上层。
                 * 7.PorterDuff.Mode.DST_IN  不是
                 * 取两层绘制交集。显示下层。
                 * 8.PorterDuff.Mode.SRC_OUT
                 * 取上层绘制非交集部分。
                 * 9.PorterDuff.Mode.DST_OUT
                 * 取下层绘制非交集部分。
                 * 10.PorterDuff.Mode.SRC_ATOP
                 * 取下层非交集部分与上层交集部分
                 * 11.PorterDuff.Mode.DST_ATOP
                 * 取上层非交集部分与下层交集部分
                 * 12.PorterDuff.Mode.XOR
                 * 异或:去除两图层交集部分
                 * 13.PorterDuff.Mode.DARKEN
                 * 取两图层全部区域,交集部分颜色加深
                 * 14.PorterDuff.Mode.LIGHTEN
                 * 取两图层全部,点亮交集部分颜色
                 * 15.PorterDuff.Mode.MULTIPLY
                 * 取两图层交集部分叠加后颜色
                 * 16.PorterDuff.Mode.SCREEN
                 * 取两图层全部区域,交集部分变为透明色
                 *
                 */
                if (sumRadius <= offRadius) {
//                    mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.MULTIPLY));
                    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, point.x, point.y, mPaint);
            }
        }
        if (cell > 0 && firstPoint != null && pieCell == 0) {
            mPaint.setColor(backGroundColor);
  
  • 14
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值