Android Canvas绘制饼图

近期学习到Android的Canvas绘制饼图,特此记录下来防止以后忘记。感谢抛物线老师的无私奉献精神。

这是完成后的效果图:


Canvas绘制饼图.png

附代码:

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.support.annotation.ColorInt;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;

import java.util.ArrayList;
import java.util.List;

public class PieView extends View {

    private static final float CENTER_X = 700; //中心点横坐标
    private static final float CENTER_Y = 700; //中心点纵坐标
    private static final  float RADIUS = 400; //圆半径

    private Paint piePaint; //饼图画笔
    private Paint linePaint; //线条画笔
    private Paint textPaint; //文字画笔

    private List pieBeanList; //饼图列表

    private RectF mRectF; //饼图矩阵

    public PieView(Context context) {
        super(context);
    }

    public PieView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init(); //初始化
    }

    public PieView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(); //初始化
    }

    /**
     * 初始化
     */
    private void init() {
        setBackgroundColor(Color.parseColor("#506E7A")); //设置屏幕背景色

        piePaint = new Paint(Paint.ANTI_ALIAS_FLAG); //初始化饼图画笔

        linePaint = new Paint(Paint.ANTI_ALIAS_FLAG); //初始化线条画笔
        linePaint.setColor(Color.WHITE); //设置字体为白色
        linePaint.setStrokeWidth(10); //设置画笔宽度

        textPaint = new Paint(Paint.ANTI_ALIAS_FLAG); //初始化文字画笔
        textPaint.setColor(Color.WHITE); //设置画笔颜色
        textPaint.setTextSize(50); //设置画笔字体大小

        //初始化圆形矩阵
        mRectF = new RectF(CENTER_X - RADIUS, CENTER_Y - RADIUS, CENTER_X + RADIUS, CENTER_Y + RADIUS);

        pieBeanList = new ArrayList(); //初始化饼图列表
        //为饼图列表填充数据
        pieBeanList.add(new PieBean("Marshmallow", 60, Color.YELLOW));
        pieBeanList.add(new PieBean("Froyo", 10, Color.LTGRAY));
        pieBeanList.add(new PieBean("Gingerbread", 10, Color.GREEN));
        pieBeanList.add(new PieBean("Ice Cream", 10, Color.BLUE));
        pieBeanList.add(new PieBean("Jelly Bean", 50, Color.CYAN));
        pieBeanList.add(new PieBean("KitKat", 100, Color.DKGRAY));
        pieBeanList.add(new PieBean("Lollipop", 120, Color.RED, true));
    }

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

        //当前开始角度
        float currentStartAngle = -60;
        for (PieBean pieBean : pieBeanList) { //遍历饼图列表
            piePaint.setColor(pieBean.getColor()); //设置饼图画笔颜色
            float sweepAngle = pieBean.getRotateAngle(); //获取旋转角度

            if (pieBean.getIsDivide()) { //饼图被分隔
                mRectF.offset(-20, -40); //圆形矩阵偏移
            }

            //绘制扇形
            canvas.drawArc(mRectF, currentStartAngle, sweepAngle, true, piePaint);

            float lineAngle = currentStartAngle + sweepAngle / 2; //获取线条的角度
            currentStartAngle += sweepAngle; //设置已旋转过的角度

            //分别求线条的横坐标起点、纵坐标起点、横坐标终点、纵坐标终点
            float lineStartX = CENTER_X + RADIUS * (float) Math.cos(lineAngle / 180 * Math.PI);
            float lineStartY = CENTER_Y + RADIUS * (float) Math.sin(lineAngle / 180 * Math.PI);
            float lineEndX = CENTER_X + (RADIUS + 50) * (float) Math.cos(lineAngle / 180 * Math.PI);
            float lineEndY = CENTER_Y + (RADIUS + 50) * (float) Math.sin(lineAngle / 180 * Math.PI);

            if (pieBean.getIsDivide()) { //饼图被分隔,线条位置偏移
                lineStartX -= 20;
                lineEndX -= 20;
                lineStartY -= 40;
                lineEndY -= 40;
            }
            canvas.drawLine(lineStartX, lineStartY, lineEndX, lineEndY, linePaint); //绘制线条

            float textX = lineEndX; //设置文字横坐标
            float textY = lineEndY; //设置文字纵坐标

            //针对角度对文字的横纵坐标变换
            if (currentStartAngle > 300 || currentStartAngle < 90) {
                textX += 20;
                textY += 20;
            } else if (currentStartAngle > 90 && currentStartAngle <= 180) {
                textX -= 60;
                textY += 60;
            } else {
                textX -= 60;
                textY -= 30;
            }
            canvas.drawText(pieBean.getTitle(), textX, textY, textPaint); //绘制文字

            if (pieBean.getIsDivide()) { //饼图被分隔
                mRectF.offset(20, 40); //圆形矩阵移动回原位
            }
        }
    }

    //饼图类
    private static class PieBean {
        private String title; //标题
        private float rotateAngle; //旋转角度
        @ColorInt private int color; //饼图颜色
        private boolean isDivide; //是否与中心分隔

        public PieBean(String title, float rotateAngle, int color) {
            this(title, rotateAngle, color, false);
        }

        public PieBean(String title, float rotateAngle, int color, boolean isDivide) {
            this.title = title;
            this.rotateAngle = rotateAngle;
            this.color = color;
            this.isDivide = isDivide;
        }

        public String getTitle() { //获取标题
            return title;
        }

        public float getRotateAngle() { //获取旋转角度
            return rotateAngle;
        }

        public int getColor() { //获取颜色
            return color;
        }

        public boolean getIsDivide() { //获取是否被分隔
            return isDivide;
        }
    }
}

参考网址:http://hencoder.com/ui-1-1/

你可能感兴趣的:(Android Canvas绘制饼图)