Android自定义View-CircleNumberProgress

继上一篇《Android自定义View-NumberProgress》绘制了一个长型的数字进度条之后,这篇是自定义一个圆形的数字进度条。
老规矩,上效果图:

Android自定义View-CircleNumberProgress_第1张图片
未标题-2.gif

分析

这个控件主要由3部分构成,第一部分为未绘制进度的部分,第二部为绘制进度的部分,最后是中间的文字部分

实现

这个实现和上一篇文章类似,具体我就不啰嗦了

自定义的属性



 
   
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
     
   

获取自定义的属性

       TypedArray a = context.obtainStyledAttributes(attrs,R.styleable.NumberProgress);
       textColor  = a.getColor(R.styleable.NumberProgress_textColor, Color.parseColor("#3498DB"));
       textSize = sp2px(context, a.getDimension(R.styleable.NumberProgress_textSize, 14f));
       unProgressColor = a.getColor(R.styleable.NumberProgress_unProgressColor, Color.parseColor("#113498DB"));
       progressColor = a.getColor(R.styleable.NumberProgress_progressColor, Color.parseColor("#3498DB"));

       currentProgress = a.getInt(R.styleable.NumberProgress_currentProgress, 0);
       maxProgress = a.getInt(R.styleable.NumberProgress_maxProgress, 100);

       arcWidth = dip2px(context,a.getDimension(R.styleable.NumberProgress_progressWidth,4));
3. 计算控件的大小
@Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        setMeasuredDimension(measureWidth(widthMeasureSpec), measureHeight(heightMeasureSpec));
    }

    private int measureWidth(int widthMeasureSpec) {
        int result;
        int mode = MeasureSpec.getMode(widthMeasureSpec);
        int size = MeasureSpec.getSize(widthMeasureSpec);
        int padding = getPaddingTop()+getPaddingBottom();
        if (mode == MeasureSpec.EXACTLY){
            result = size;
        }else{
            result = getSuggestedMinimumHeight();
            result += padding;
            if (mode == MeasureSpec.AT_MOST){
                result = Math.max(result, size);
            }
        }
        return result;
    }

    @Override
    protected int getSuggestedMinimumWidth() {
        return (int) dip2px(getContext(),100);
    }

    @Override
    protected int getSuggestedMinimumHeight() {
        return (int) dip2px(getContext(),100);
    }
4. 计算图形大小以及位置
  1. 需要绘制的东西
    1、未绘制的进度条就是一个空心的圆
    2、绘制的进度条是一个弧
    3、中间的文字
drawCircle(float cx, float cy, float radius,Paint paint)
// 绘制圆,参数一是中心点的x轴,参数二是中心点的y轴,参数三是半径,参数四是画笔
drawArc(RectF oval, float startAngle, float sweepAngle, boolean useCenter, Paint paint)
//画弧,参数一是RectF对象,一个矩形区域椭圆形的界限用于定义在形状、大小、电弧,参数二是起始角(度)在电弧的开始,
//参数三扫描角(度)开始顺时针测量的,参数四是如果这是真的话,包括椭圆中心的电弧,并关闭它,如果它是假这将是一个弧线,参数五是Paint对象;
drawText(String text, float x, floaty, Paint paint)  
//渲染文本,Canvas类除了上面的还可以描绘文字,参数一是String类型的文本,参数二x轴,参数三y轴,参数四是Paint对象。
  1. 首先,我们确定空心的圆的圆心和半径
// 绘制浅色圆环
        // 1.圆心(x,y)坐标值
        float centerX = (getWidth()-getPaddingLeft()-getPaddingRight())/2.0f;
        float centerY = (getHeight() - getPaddingTop() - getPaddingBottom())/2.0f;
        // 2.圆环半径
        float radius;
        if (getWidth() >= getHeight()) {
            radius = (centerY - arcWidth / 2);
        }else{
            radius = (centerX - arcWidth / 2);
        }
        canvas.drawCircle(centerX,centerY,radius,circlePaint);
  1. 绘制弧

绘制弧度需要一个RectF对象,就是限定弧度形状、大小;
弧度为0到当前进度除以100乘以一圈的度数360,这里这个RectF对象的大小就是圆心加减半径:

oval.left = centerX - radius;
oval.right = centerX + radius;
oval.top = centerY - radius;
oval.bottom = centerY+radius;
canvas.drawArc(oval, 0, (float)360 * currentProgress / (float)maxProgress, false, arcPaint);
  1. 绘制文字

绘制文字比较简单就不说了,直接上代码

currentDrawText = String.format("%d", currentProgress * 100 /maxProgress);
currentDrawText = (currentDrawText)+"%";
float drawTextWidth = textPaint.measureText(currentDrawText);
canvas.drawText(currentDrawText,centerX-drawTextWidth/2.0f,centerY-((textPaint.descent() + textPaint.ascent()) / 2.0f),textPaint);
5. 测试

测试和上篇文章是一样的
再来一遍效果图


Android自定义View-CircleNumberProgress_第2张图片
未标题-2.gif

完整代码请移步github:https://github.com/823546371/NumberProgress
本文地址:http://www.jianshu.com/p/6312861363b6
尊重原创,转载请注明:From 晓峰残月(http://jwenfeng.com) 侵权必究!

你可能感兴趣的:(Android自定义View-CircleNumberProgress)