转载

Android自定义View-CircleNumberProgress

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

分析

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

实现

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

自定义的属性

<?xmlversion="1.0" encoding="utf-8"?>   <resources>    <declare-styleablename="NumberProgress">      <!-- 文字大小 -->       <attrname="textSize" format="dimension"/>       <!-- 文字颜色 -->       <attrname="textColor" format="color"/>       <!-- reached的高度 -->       <attrname="reachedHeight" format="dimension"/>       <!-- reached的颜色 -->       <attrname="reachedColor" format="color"/>       <!-- unReached的高度 -->       <attrname="unReachedHeight" format="dimension"/>       <!-- unReached的颜色 -->       <attrname="unReachedColor" format="color"/>       <!-- 当前进度 -->       <attrname="currentProgress" format="integer"/>       <!-- 总进度 -->       <attrname="maxProgress" format="integer"/>       <!-- unProgress颜色 -->       <attrname="unProgressColor" format="color"/>       <!-- progress颜色 -->       <attrname="progressColor" format="color"/>       <!-- progress宽度 -->       <attrname="progressWidth" format="dimension"/>    </declare-styleable>  </resources>   

获取自定义的属性

        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,Paintpaint) // 绘制圆,参数一是中心点的x轴,参数二是中心点的y轴,参数三是半径,参数四是画笔 drawArc(RectFoval, float startAngle, float sweepAngle, boolean useCenter, Paintpaint) //画弧,参数一是RectF对象,一个矩形区域椭圆形的界限用于定义在形状、大小、电弧,参数二是起始角(度)在电弧的开始, //参数三扫描角(度)开始顺时针测量的,参数四是如果这是真的话,包括椭圆中心的电弧,并关闭它,如果它是假这将是一个弧线,参数五是Paint对象; drawText(String text, float x, floaty, Paintpaint)   //渲染文本,Canvas类除了上面的还可以描绘文字,参数一是String类型的文本,参数二x轴,参数三y轴,参数四是Paint对象。   
  2. 首先,我们确定空心的圆的圆心和半径
    // 绘制浅色圆环     // 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);   
  3. 绘制弧

绘制弧度需要一个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

原文  http://jwenfeng.com/archives/179
正文到此结束
Loading...