android圆饼图占比

本文介绍如何在Android中创建一个自定义的圆饼图。通过继承View类并重写onMeasure和onDraw方法,将视图处理为正方形,并绘制饼图。当圆的某一部分角度超过360度时,超出部分不会显示。文章提供了源码下载链接,供进一步研究。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

先来一张效果图预览

代码其实很简单,鄙人处于研究阶段,有更好的建议欢迎指出。

实现自定义view第一步继承view类,

然后画图的渲染顺序为先执行onMesure方法计算view的宽高,这里把整个view处理成一个正方形,其它图形的有待研究

先把全局变量设置出来,以便不影响思维顺序

private int viewWidth = 0;
    private int viewHeight = 0;
    private float contentPadding = 0f;//默认边距
    private float defaultPadding = 5f;
    private float colorCircleWidth = 30f;//默认弧形宽度
    float startRadian = 180;//起始角度水平左边开始
    private int backGroundColor = 0;

    List<List<CircleBean>> circleNumList;


@Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        Log.e("onMeasure", "onMeasure");
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        viewWidth = getWidth();
        viewHeight = getHeight();

        int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
        int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);
        int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);
        int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec);
        // 在wrap_content的情况下默认长度为200dp
        int minSize = 0;
        if (widthSpecSize > heightSpecSize) {
            minSize = heightSpecSize;
        } else if (widthSpecSize < heightSpecSize) {
            minSize = widthSpecSize;
        }
        // wrap_content的specMode是AT_MOST模式,这种情况下宽/高等同于specSize
        // 查表得这种情况下specSize等同于parentSize,也就是父容器当前剩余的大小
        // 在wrap_content的情况下如果特殊处理,效果等同martch_parent
        if (widthSpecMode == MeasureSpec.AT_MOST && heightSpecMode == MeasureSpec.AT_MOST) {
            setMeasuredDimension(minSize, minSize);
            viewWidth = viewHeight = minSize;
        } else if (widthSpecMode == MeasureSpec.AT_MOST) {
            setMeasuredDimension(minSize, heightSpecSize);
            viewWidth = minSize;
            viewHeight = heightSpecSize;
        } else if (heightSpecMode == MeasureSpec.AT_MOST) {
            setMeasuredDimension(widthSpecSize, minSize);
            viewWidth = widthSpecSize;
            viewHeight = minSize;
        }
    }
viewWidth和viewHeight为一个全局的变量,用于设置绘图的背景

计算完view宽高后执行onDraw方法进行渲染我们想要的图形样式

@Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        Log.e("onDraw", "onDraw");

        //设置背景颜色
        Paint bgPaint = new Paint();
        bgPaint.setColor(backGroundColor);
        canvas.drawRect(0, 0, viewWidth, viewHeight, bgPaint);

        Paint mArcPaint = new Paint();
        mArcPaint.setAntiAlias(true);
        mArcPaint.setColor(Color.parseColor("#ff6600"));
        mArcPaint.setStyle(Paint.Style.STROKE);
        mArcPaint.setStrokeWidth(colorCircleWidth);//线宽

        drawableCircle(canvas, mArcPaint, circleNumList);
    }
private void drawableCircle(Canvas canvas, Paint circlePaint, List<List<CircleBean>> circleNumList) {
        if (defaultPadding * circleNumList.size() > (viewWidth / 2 - defaultPadding)) {
            colorCircleWidth = (viewWidth / 2 - defaultPadding) / circleNumList.size();
        }
        float circleWidth = defaultPadding;
        for (int j = 0; j < circleNumList.size(); j++) {
            RectF mRectF = new RectF(circleWidth, circleWidth, viewWidth - circleWidth, viewHeight - circleWidth);
            List<CircleBean> circleBeanList = circleNumList.get(j);
            startRadian = 180;
            float scalRadian = 0;
            for (int i = 0; i < circleBeanList.size(); i++) {
                CircleBean circleBean = circleBeanList.get(i);
                scalRadian = circleBean.getRadianValue();
                String color = circleBean.getRadianColor();
                circlePaint.setColor(Color.parseColor(color));

                if ((startRadian + scalRadian) >= (360 + 180)) {//弧度总和超过一圈在起始点结束
                    scalRadian = ((360 + 180) - startRadian);
                }
                canvas.drawArc(mRectF, startRadian, scalRadian, false, circlePaint);
                startRadian += circleBean.getRadianValue();
            }
            circleWidth += colorCircleWidth + 1;
        }
    }

此处图表的数据为一个重叠的数据,每一层数据可以绘画一个圆,bean里面可以设置每一段弧度范围和颜色。

(备注)当一层圆的数据超过360弧度时只 会显示一个圆的范围,超出360度的值不显示


bean里面有两个参数可供使用

public class CircleBean {
    private float radianValue;//每段弧度的值
    private String radianColor;//每段弧度的颜色

    public float getRadianValue() {
        return radianValue;
    }

    public void setRadianValue(float radianValue) {
        this.radianValue = radianValue;
    }

    public String getRadianColor() {
        return radianColor == null ? "" : radianColor;
    }

    public void setRadianColor(String radianColor) {
        this.radianColor = radianColor;
    }
}

当然还少不了自定义属性,在xml中可以直接设置圆圈的宽度,圆边距和整个view的背景颜色

<resources>
    <declare-styleable name="circle_view_styleable" >
        <attr name="viewPadding" format="dimension"/>
        <attr name="circleWidth" format="dimension"/>
        <attr name="backGroundColor" format="color" />
    </declare-styleable>
</resources>


public CircleView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        TypedArray custorm = context.obtainStyledAttributes(attrs, R.styleable.circle_view_styleable);
        contentPadding = custorm.getDimension(R.styleable.circle_view_styleable_viewPadding, 0f);
        colorCircleWidth = custorm.getDimension(R.styleable.circle_view_styleable_circleWidth, 30f);
        backGroundColor = custorm.getColor(R.styleable.circle_view_styleable_backGroundColor, Color.parseColor("#ffffff"));

        defaultPadding = colorCircleWidth / 2 + contentPadding;
        custorm.recycle();

    }


做完项目剩余时间来写的,如果 不是很完整可以下载工程来看。(工程采用as工具编写)


项目免费下载地址点击打开链接


评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值