Android 第一自定的View-圆形图表

上一个项目有一个功能用一个圆形的图表来显示数据,当时时间紧张,然后就在网上搜了一个开源框架来实现的,叫做MPAndroidChart。最近没事看了下之前的这个功能,觉得实现这个功能挺简单的,然后自己谢谢呗。在这记录一下写出的过程吧。

首先定义一个RoundChartView的类extends于View,重写了onMeasure(int widthMeasureSpec, int heightMeasureSpec)和onDraw(Canvas canvas)两个方法。在onMeasure方法中取得控件的宽和高,然后根据Math.min这个方法获取最小值,再设置要画圆的半径,代码如下:
private int height;
    private int width;
    private int roundRadius;//圆饼半径

@Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        height = MeasureSpec.getSize(heightMeasureSpec);
        width = MeasureSpec.getSize(widthMeasureSpec);
        if (height == 0||width == 0) {
            roundRadius = 0;
                }else {
            roundRadius = Math.min(height,width)/3;
        }
    }
再设置画笔,获取画笔的方法:Paint paint = new Paint();接下来是对画笔的常用设置介绍(如果paint不设置setStyle,默认是填充全部):
Paint paint = new Paint()
paint .setAntiAlias(true);//去画笔的锯齿
paint.setStyle(Paint.Style.STROKE);//设置画笔的风格,paint.Style.有三个常量FILL、STROKE、FILL_AND_STROKE,分别代表的意思:FILL 填充内部(默认),STROKE 只描边,FILL_AND_STROKE 填充内部与描边;
paint.setStrokeWidth(float);//如果风格为STROKE的时候,可以设置边的宽度。
首先我先画了一个最边缘的圆,画笔风格为STROKE,颜色设置为透明灰色,具体实现代码如下:

Paint shadePaint = new Paint();
        shadePaint.setColor(Color.parseColor("#33868990"));
        shadePaint.setAntiAlias(true);
        shadePaint.setStyle(Paint.Style.STROKE);
        shadePaint.setStrokeWidth(20);//设置阴影部分的宽度

 @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        this.width = getWidth();
        if (roundRadius != 0&&arcColor != null && textStr != null && percentage != null
                && arcColor.length == textStr.length
                && textStr.length == percentage.length) {
            canvas.drawCircle(width / 2, height / 2, roundRadius, shadePaint);//画圆饼的外圈颜色
            setArc(canvas);//绘制每个盘快
        }

    }
接下来画每个盘快
/**
     * 绘制每个盘快
     */
    private void setArc(Canvas canvas) {
        int startAngle = 0;//设置盘快的起始角度
        for (int i = 0; i < arcColor.length; i++) {
            int angle;
            if (i == arcColor.length - 1) {
                angle = 360-startAngle;
            }else {
                angle = (int) (360 * percentage[i]);//设置每个盘快的角度
            }
            RectF rect = new RectF(width / 2 - roundRadius + 5, height / 2 - roundRadius + 5
                    , width / 2 + roundRadius - 5, height / 2 + roundRadius - 5);//设置盘快的区域
            dishPaint.setColor(arcColor[i]);//设置每个盘快的颜色
            canvas.drawArc(rect, startAngle, angle, true, dishPaint);//绘制盘快
            drawText(canvas, textStr[i], rect, startAngle, angle, percentage[i]);//绘制每个盘快上的字
            startAngle += angle;

        }
        drawCenterRound(canvas);//绘制中心圆
    }

下面是绘制每个盘快上的文字

/**
     * 绘制每个盘快的文字
     * str 板块的名字
     * rect 绘制板块的范围
     * startAngle 开始的角度
     * angle 旋转的角度
     * percentage 盘快所占的百分比
     */
    private void drawText(Canvas canvas, String str, RectF rect, int startAngle, int angle, Double percentage) {
        Path path = new Path();//绘制每个盘快文字的路径
        path.addArc(rect, startAngle, angle);//设置路径的位置以及长度
        textPaint.setTextSize(25);//设置每个盘快字体的大小为每个弧度大小的十分之一
        int textLe = (int) textPaint.measureText(str);//文字的长度
        int hOffset = (int) (((roundRadius * 2) * Math.PI) * percentage - textLe) / 2;//水平偏移长度
        int vOffset = roundRadius / 5;//垂直偏移长度
        canvas.drawTextOnPath(str, path
                , hOffset, vOffset, textPaint);
    }
最后是绘制一个中心圆以及圆上的位置
/**
     * 绘制中心的圆和中心圆的文字
     */
    private void drawCenterRound(Canvas canvas) {
        int centerRoundRadius = roundRadius / 3;//中心圆的半径
        centerTextPaint.setTextSize(centerRoundRadius / 3);//设置中心字体的大小,为中心小圆的3分之一
        centerBelowTextPaint.setTextSize(centerRoundRadius / 4);//设置中心字体的大小,为中心小圆的4分之一
        int centerTextWidth = (int) centerTextPaint.measureText("总和");
        int centerBlowTextWidth = (int) centerBelowTextPaint.measureText("520");
        canvas.drawCircle(width / 2, height / 2, centerRoundRadius, centerPaint);
        canvas.drawText("总和",
                (width / 2 - centerRoundRadius) + (centerRoundRadius * 2 - centerTextWidth) / 2
                , height / 2, centerTextPaint);
        canvas.drawText("520",
                (width / 2 - centerRoundRadius) + (centerRoundRadius * 2 - centerBlowTextWidth) / 2
                , height / 2 + centerRoundRadius / 3 + 5, centerBelowTextPaint);
    }
最后说一下RectF 这个我的理解为相当于要绘制的内容所在的区域,RectF f = new RectF (float left, float top, float right, float bottom),中四个参数的说明用一个图片来说明吧(绘制圆会以RectF的中心坐标为圆心来画圆):

这里写图片描述

代码地址

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值