android圆饼图占比

先来一张效果图预览

android圆饼图占比_第1张图片

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

实现自定义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> 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> 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 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的背景颜色


    
        
        
        
    


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工具编写)


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


你可能感兴趣的:(android圆饼图占比)