自定义view 雷达图 百分比维度图

戏子无情 提交于 2020-01-19 08:48:21

效果图:

具体实现



public class RadarView extends View {
    private static final float maxValue = 100; // 最大刻度值

    private int count = 5; // 数据个数
    private float angle = (float) (Math.PI * 2 / count);
    private Paint circlePaint; // 圆环画笔
    private float radius; // 最大半径
    private int centerX, centerY; // 中心点
    private Paint mainCirclePaint; // 整个圆环填充画笔

    private Paint graduationValuePaint; // 刻度值画笔
    private String[] graduationValues = {"0", "20", "40", "60", "80", "100"};

    private Paint titlePaint; // 标签画笔
    private String[] titles = {"标签a", "标签b", "标签c", "标签d", "标签f"};
    private double[] data = {70, 50, 67, 80, 56};

    private Paint dotPaint; // 外环上的圆点画笔

    private Paint regionPaint; // 数据区域画笔

    private int ten;

    public RadarView(Context context) {
        super(context);
        init();
    }

    public RadarView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public RadarView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init() {
        DisplayMetrics dm = getResources().getDisplayMetrics();
        int screenWidth = dm.widthPixels;

        ten = (int) (0.0094 * screenWidth);
        // 圆环区域
        circlePaint = new Paint();
        circlePaint.setAntiAlias(true);
        circlePaint.setColor(getResources().getColor(R.color.circle_stroke_color));
        circlePaint.setStyle(Paint.Style.STROKE);
        mainCirclePaint = new Paint();
        mainCirclePaint.setAntiAlias(true);
        mainCirclePaint.setColor(getResources().getColor(R.color.circle_fill_color));
        mainCirclePaint.setStyle(Paint.Style.FILL);
        // 刻度值
        graduationValuePaint = new Paint();
        graduationValuePaint.setAntiAlias(true);
        graduationValuePaint.setColor(getResources().getColor(R.color.int_value_color));
        Typeface typeface = Typeface.create(Typeface.SANS_SERIF, Typeface.BOLD);
        graduationValuePaint.setTypeface(typeface);
        graduationValuePaint.setTextSize(18);
        graduationValuePaint.setStyle(Paint.Style.FILL);
        // 标签画笔
        titlePaint = new Paint();
        titlePaint.setAntiAlias(true);
        titlePaint.setColor(getResources().getColor(R.color.black_color));
        Typeface titleTypeface = Typeface.create(Typeface.SANS_SERIF, Typeface.BOLD);
        titlePaint.setTypeface(titleTypeface);
        titlePaint.setTextSize(24);
        titlePaint.setStyle(Paint.Style.FILL);
        // 外环上的圆点画笔
        dotPaint = new Paint();
        dotPaint.setAntiAlias(true);
        dotPaint.setColor(getResources().getColor(R.color.blue_dot_color));
        dotPaint.setStyle(Paint.Style.FILL);
        // 数据区域画笔
        regionPaint = new Paint();
        regionPaint.setAntiAlias(true);
        regionPaint.setStyle(Paint.Style.FILL_AND_STROKE);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        radius = Math.min(h, w) / 2 * 0.7f;
        centerX = w / 2;
        centerY = h / 2;
        postInvalidate();
        super.onSizeChanged(w, h, oldw, oldh);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        // 画底层圆环
        drawCircle(canvas);
        // 画刻度值
        drawGraduationValue(canvas);
        // 画文字标题
        drawTitles(canvas);
        // 画有效区域
        drawRegion(canvas);
    }

    private void drawGraduationValue(Canvas canvas) {
        Paint.FontMetrics fontMetrics = graduationValuePaint.getFontMetrics();
        // 文本高度
        float fontHeight = fontMetrics.descent - fontMetrics.ascent;
        // 刻度值X轴坐标
        float graduationX = centerX - fontHeight * 6 / 5;
        // 网层直接距离
        float r = radius / 5;
        for (int i = 1; i < 6; i++) {
            graduationX = graduationX + 20;
            float curR = r * i;
            float graduationY = centerY + curR - 20;
            canvas.drawText(graduationValues[i], graduationX, graduationY, graduationValuePaint);
        }
    }

    private void drawCircle(Canvas canvas) {
        // 画带有填充色的背景圆
        canvas.drawCircle(centerX, centerY, radius, mainCirclePaint);
        // 画圆框
        float r = radius / count;
        for (int i = 1; i < 6; i++) {
            float curR = i * r; // 每一个圆环的半径
            canvas.drawCircle(centerX, centerY, curR, circlePaint);
        }
        // 画十字直线
        canvas.drawLine(centerX - radius, centerY, centerX + radius, centerY, circlePaint); // 横线
        canvas.drawLine(centerX, centerY - radius, centerX, centerY + radius, circlePaint); // 竖线
    }

    private void drawTitles(Canvas canvas) {
        for (int i = 0; i < count; i++) {
            float x = (float) (centerX + radius * Math.cos(angle * i));
            float y = (float) (centerY + radius * Math.sin(angle * i));
            Paint.FontMetrics fontMetrics = titlePaint.getFontMetrics();
            // 文本高度
            float fontHeight = fontMetrics.descent - fontMetrics.ascent;
            Rect rect = new Rect();
            titlePaint.getTextBounds(titles[i], 0, titles[i].length(), rect);
            // 文本宽度
            float fontWidth = rect.width();
            // 文本坐标
            float titleX = (float) (x + fontWidth * Math.cos(angle * i)) - (fontWidth / 2);
            float titleY = (float) (y + fontHeight * Math.sin(angle * i));
            canvas.drawText(titles[i], titleX, titleY, titlePaint);
            // 画圆点
            canvas.drawCircle(x, y, 10, dotPaint);
        }

    }

    private void drawRegion(Canvas canvas) {
        Path path = new Path();
        regionPaint.setColor(getResources().getColor(R.color.region_color));
        regionPaint.setAlpha(255);
        for (int i = 0; i < count; i++) {
            double percent = data[i] / maxValue;
            float x = (float) (centerX + radius * Math.cos(angle * i) * percent);
            float y = (float) (centerY + radius * Math.sin(angle * i) * percent);
            if (i == 0) {
                path.moveTo(x, centerY);
            } else {
                path.lineTo(x, y);
            }
            canvas.drawCircle(x, y, 10, regionPaint);
        }
        path.close();
        regionPaint.setColor(getResources().getColor(R.color.blue_dot_color));
        regionPaint.setStyle(Paint.Style.STROKE);
        canvas.drawPath(path, regionPaint);
        // 填充色
        regionPaint.setColor(getResources().getColor(R.color.region_color));
        regionPaint.setStyle(Paint.Style.FILL_AND_STROKE);
        regionPaint.setAlpha(127);
        canvas.drawPath(path, regionPaint);
    }
}

根据需要,自行修改代码即可

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!