Android-自定义环形统计图

由于前段时间回老家处理事情,所以这篇文章拖到了今天才有时间来写,请大家谅解!

由于在群里面有同学需要环形统计图,所以抽了点时间写出来,下面为大家提供上源码,以供大家交流分析指正。
先上效果图:
环形统计图

以下贴上源码:

/**
 * Created by lxh on 2017/2/10.
 * QQ-632671653
 */

public class CircularStatisticsView extends View {


    /**
     * 第一圈的颜色
     */
    private int mFirstColor = Color.BLUE;
    /**
     * 第二圈的颜色
     */
    private int mSecondColor = Color.RED;
    /**
     * 圈的宽度
     */
    private float mCircleWidth = 200;
    /**
     * 画笔
     */
    private Paint mPaint;
    /**
     * 当前进度
     */
    private int mProgress = 20;
    /**
     * 剩余文字
     */
    private String reminderText = "剩余";
    /**
     * 进度文字
     */
    private String progressText = "已使用";

    /**
     * 中心x坐标
     */
    int centreX;
    /**
     * 中心y坐标
     */
    int centerY;

    public CircularStatisticsView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public CircularStatisticsView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

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


    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        mPaint = new Paint();
        centreX = getWidth() / 2; // 获取圆心的x坐标
        centerY = getHeight() / 2;
        int radius = centreX/2;// 半径
        mPaint.setStrokeWidth(mCircleWidth); // 设置圆环的宽度
        mPaint.setAntiAlias(true); // 消除锯齿
        mPaint.setStyle(Paint.Style.STROKE); // 设置空心
        RectF oval = new RectF(centreX - radius, centerY - radius, centreX + radius, centerY + radius); // 用于定义的圆弧的形状和大小的界限
        mPaint.setColor(mFirstColor); // 设置圆环的颜色
        canvas.drawCircle(centreX, centerY, radius, mPaint); // 画出圆环
        mPaint.setColor(mSecondColor); // 设置圆弧的颜色
        canvas.drawArc(oval, -90, mProgress, false, mPaint); // 根据进度画圆弧

        //获取进度圆弧的中心点
        float textX1 = (float) (centreX + (radius+mCircleWidth/2)*Math.cos(2*Math.PI*(mProgress/2-90)/360));
        float textY1 = (float) (centerY + (radius+mCircleWidth/2)*Math.sin(2*Math.PI*(mProgress/2-90)/360));
        Paint paint = new Paint();
        paint.setStrokeWidth(2); // 设置圆环的宽度
        paint.setAntiAlias(true); // 消除锯齿
        paint.setColor(mSecondColor);
        paint.setTextSize(30);
        drawText(canvas,progressText+getPer(mProgress,360),textX1,textY1,paint);
        float textX2 = (float) (centreX + (radius+mCircleWidth/2)*Math.cos(2*Math.PI*((mProgress-360)/2-90)/360));
        float textY2 = (float) (centerY + (radius+mCircleWidth/2)*Math.sin(2*Math.PI*((mProgress-360)/2-90)/360));
        paint.setColor(mFirstColor);
        drawText(canvas,reminderText+getPer(360-mProgress,360),textX2,textY2,paint);
    }

    /**
     * 计算百分比
     * @param now
     * @param total
     * @return
     */
    private String getPer(int now,int total){
        // 创建一个数值格式化对象
        NumberFormat numberFormat = NumberFormat.getInstance();

        // 设置精确到小数点后2位
        numberFormat.setMaximumFractionDigits(2);

        String result = numberFormat.format((float) now / (float) total * 100);

        return result+"%";
    }

    /**
     * 设置剩余进度颜色
     * @param color
     */
    public void setReminderColor(int color){
        mFirstColor = color;
        invalidate();
    }

    /**
     * 设置当前进度颜色
     * @param color
     */
    public void setProgressColor(int color){
        mSecondColor = color;
        invalidate();
    }

    /**
     * 设置剩余进度文字
     * @param text
     */
    public void setReminderText(String text){
        reminderText = text;
        invalidate();
    }

    /**
     * 设置当前进度文字
     * @param text
     */
    public void setProgressText(String text){
        progressText = text;
        invalidate();
    }

    /**
     * 设置圆环宽度
     * @param width
     */
    public void setCircleWidth(int width){
        mCircleWidth = width;
        invalidate();
    }

    /**
     * 设置当前进度
     * @param total  总量
     * @param now    当前进度量
     */
    public void setProgress(float total,float now){
        mProgress = (int) ((now/total)*360);
        postInvalidate();
    }
    /**
     * 绘制文字
     * @param canvas
     * @param string
     * @param firstX
     * @param firstY
     * @param paint
     */
    private void drawText(Canvas canvas,String string,float firstX,float firstY,Paint paint){
        float endX1 = 0;
        float endY1 = 0;
        float endX2 = 0;
        float endY2 = 0;
        float textX = 0;
        float textY = 0;
        //初始点位于第四象限
        if (firstX<=centreX&&firstY<=centerY){
            endX1 = firstX - 50;
            endY1 = firstY - 50;
            endX2 = firstX-200;
            endY2 = firstY-50;
            textX = endX2;
            textY = endY2-10;
        }
        //初始点位于第三象限
        if (firstX<centreX&&firstY>centerY){
            endX1 = firstX - 50;
            endY1 = firstY + 50;
            endX2 = firstX - 200;
            endY2 = firstY + 50;
            textX = endX2;
            textY = endY2+40;
        }
        //初始点位于第一象限
        if (firstX>centreX&&firstY<centerY){
            endX1 = firstX + 50;
            endY1 = firstY - 50;
            endX2 = firstX + 200;
            endY2 = firstY - 50;
            textX = endX1;
            textY = endY2-10;
        }
        //初始点位于第二象限
        if (firstX>=centreX&&firstY>=centerY){
            endX1 = firstX + 50;
            endY1 = firstY + 50;
            endX2 = firstX + 200;
            endY2 = firstY + 50;
            textX = endX1;
            textY = endY2+40;
        }
        canvas.drawLine(firstX,firstY,endX1,endY1,paint);
        canvas.drawLine(endX1,endY1,endX2,endY2,paint);
        canvas.drawText(string,textX,textY,paint);
    }

}

在xml中直接使用:

<com.lxh.usermodule.CircularStatisticsView
        android:id="@+id/circularStatisticsView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

在activity中初始化各项属性:

circularStatisticsView = (CircularStatisticsView) findViewById(R.id.circularStatisticsView);
        circularStatisticsView.setOnClickListener(this);
        circularStatisticsView.setReminderText("剩余");
        circularStatisticsView.setProgressText("已使用");
        circularStatisticsView.setProgress(15638,2546);
        circularStatisticsView.setReminderColor(Color.parseColor("#FF0000FF"));
        circularStatisticsView.setProgressColor(Color.parseColor("#FFFF0000"));
        circularStatisticsView.setCircleWidth(200);

源码中有详细的注解,由于时间因素,本控件还有很多需要完善的地方,希望大家自行扩展完善,感谢大家。更多技术交流请加本人QQ:632671653,微信:15123534435

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值