486_带动画的饼图扇形图

来源:互联网 发布:网络视频管理系统 编辑:程序博客网 时间:2024/05/01 12:26




带动画的饼图扇形图




public class CircleView extends View {


    private Context context;
    private Paint paint;
    private List<Double> valueList;
    private List<Integer> colorList;
    private List<Double> percentList = new ArrayList<>();
    private List<Double> angleList = new ArrayList<>();
    private float minAngle = 3f;
    private float nowAngle = 360;


    public void setValueAndColorArray(List<Double> valueList, List<Integer> colorList) {
        if (valueList == null || colorList == null || valueList.size() != colorList.size()) {
            return;
        }
        this.valueList = valueList;
        this.colorList = colorList;
        //如果有0的,就删除掉
        while (isListHaveZero() != -1) {
            int position = isListHaveZero();
            valueList.remove(position);
            colorList.remove(position);
        }
        //算出总数
        double sum = 0;
        for (double value : valueList) {
            sum = sum + value;
        }
        //算出百分比
        for (double value : valueList) {
            double percent = value / sum;
            percentList.add(percent);
        }
        //算出角度
        for (double percent : percentList) {
            double angle = percent * 360;
            angleList.add(angle);
        }
        //平衡角度
        while (isListHaveSmall() != -1) {
            int position = isListHaveSmall();
            double angle = angleList.get(position);
            double chazhi = minAngle * 2 - angle;
            angleList.set(position, (double) (minAngle * 2));
            int maxPosition = ListUtil.getMaxPosition(angleList);
            double max = angleList.get(maxPosition);
            max = max - chazhi;
            angleList.set(maxPosition, max);
        }
    }


    private int isListHaveSmall() {
        for (int i = 0; i < angleList.size(); i++) {
            if (angleList.get(i) < minAngle * 2) {
                return i;
            }
        }
        return -1;
    }


    private int isListHaveZero() {
        for (int i = 0; i < valueList.size(); i++) {
            if (valueList.get(i) == 0) {
                return i;
            }
        }
        return -1;
    }


    public CircleView(Context context) {
        this(context, null);
    }


    public CircleView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }


    public CircleView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        this.context = context;
        paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeWidth(dp20);
    }


    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        setMeasuredDimension(dp200, dp200);
    }


    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);


        RectF rectF = new RectF(dp10, dp10, dp200 - dp10, dp200 - dp10);
        float alreadyAngle = 0;


        if (ListUtil.isEmpty(valueList) || ListUtil.isEmpty(colorList)) {


            paint.setColor(Color.parseColor("#EFEFEF"));
            canvas.drawArc(rectF, 0, 360, false, paint);


        } else {
            for (int i = 0; i < angleList.size(); i++) {
                int color = colorList.get(i);
                paint.setColor(color);
                double angleDouble = angleList.get(i);
                float angle = (float) angleDouble;
                if (i == 0) {
                    //第一个
                    if (angle - minAngle <= nowAngle) {
                        canvas.drawArc(rectF, 0, angle - minAngle, false, paint);
                    } else {
                        canvas.drawArc(rectF, 0, nowAngle, false, paint);
                        return;
                    }
                } else if (i == angleList.size() - 1) {
                    //最后一个
                    float lastAngle = 360 - alreadyAngle;
                    if (alreadyAngle + lastAngle - minAngle <= nowAngle) {
                        canvas.drawArc(rectF, alreadyAngle, lastAngle - minAngle, false, paint);
                    } else {
                        canvas.drawArc(rectF, alreadyAngle, nowAngle - alreadyAngle - minAngle, false, paint);
                        return;
                    }
                } else {
                    //中间的
                    if (alreadyAngle + angle - minAngle <= nowAngle) {
                        canvas.drawArc(rectF, alreadyAngle, angle - minAngle, false, paint);
                    } else {
                        canvas.drawArc(rectF, alreadyAngle, nowAngle - alreadyAngle - minAngle, false, paint);
                        return;
                    }
                }
                alreadyAngle = alreadyAngle + angle;
            }
        }
    }


    public void playAnimation() {
        nowAngle = 0;
        handler.sendEmptyMessage(0);
    }


    private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            if (nowAngle < 360) {
                nowAngle = nowAngle + 6;
                CircleView.this.invalidate();
                sendEmptyMessageDelayed(0, 5);
            }
        }
    };
}



0 0