自定义圆环进度条

883 阅读8分钟
原文链接: www.cnblogs.com
使用自定义控件绘制一个圆环,需要重现的方法是OnDraw()实现对view的绘制,从而输出符合自己需求的view控件 观察圆环的组成部分:   外层圆+中间百分比文字+不断变化进度的弧形圈   --->分析:每一个组成部分需要的属性,构成几个关键的自定义属性          1:外层圆的颜色          2:弧形进度圈的颜色          3:中间百分比文字的颜色          4:中间百分比文字的大小          5:圆环的宽度(作为进度弧形圈的宽度)          6:*首页当中也有一个圆环进度,为了兼容使用首页的圆环进度,增加一个自定义属性,绘制进度弧形圈的风格(实心[Fill],空心[Stroken])     分析完毕-->绘制步骤:   1:构造方法当中初始化画笔对象,获取自定义的属性值.   2:重写Ondraw方法     ---2.1:绘制最外层的圆          -关键方法canvas.drawCircle(center, center, radius, paint); //画出圆环          *:计算半径、中心点坐标、画笔设置         中心点坐标         int center = getWidth() / 2; //获取圆心的x坐标         半径:         int radius = (int) (center - roundWidth/2) ---画图说明最容易理解       ---2.2:绘制中间的百分比文字         --关键方法:canvas.drawText(percent + "%", center - textWidth / 2, center + textSize / 2, paint); //画出进度百分比                     测量画笔上的文本宽度                     float textWidth = paint.measureText(percent + "%");                          画笔设置          绘制的文字的位置,由参数2,3的X,Y坐标值决定--圆环的中心点位置显示          X:表示从哪开始绘制,如果你直接中心点开始绘制-->画图说明最容易理解            -->正确的X=center - textWidth / 2;Y = center + textSize / 2 --(因为android坐标系与数学坐标系Y轴值是相反的,也可以画图说明,这里的textsize就可以代表高度,paint.measureText测量方法执行之后,默认的文字高度就是根据文字大小计算的,相当于wrap_content,所以textSize就是本身文字所占的高度值)          *:绘制的进度要转换为百分比形式:int percent = (int) (((float) progress / (float) max) * 100);       ---2.3:绘制进度弧形圈           ---关键方法:canvas.drawArc(oval, 0, 360 * progress / max, false, paint);  //根据进度画圆弧         参数解释:         oval:绘制的弧形的范围轮廓         0:从多少角度开始绘制         360 * progress / max:绘制弧形扫过的角度对应的区域         false:不包含圆心,如果是true,表示包含圆心         paint:绘制使用的画笔             画笔设置         paint.setStrokeWidth(roundWidth); //设置进度弧形圈的宽度,必须保持和外层圆的StrokeWidth一致,确保弧形圈绘制的时候覆盖的范围就是外层圆的宽度         paint.setColor(roundProgressColor); //设置进度的颜色                    弧形范围计算         RectF oval = new RectF(center - radius, center - radius, center                 + radius, center + radius); --->画图说明最容易理解         *:注意,因为progress是相对于100当中占比多少,而弧形总共是按照角度分成360分的,所以绘制弧形圈指定参数扫过的区域角度需要计算转换一下         =360 * progress / max(max=100)            最后提供一个设置进度,根据进度重新绘制圆环的方法           .....圆环绘制自定义控件分析end...........................................................................|  
RoundProgress

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 public class RoundProgress extends View {     private Paint paint = new Paint();     private int roundColor;     private int roundProgressColor;     private int textColor;     private float textSize;     private float roundWidth;     private int max = 100 ;     private int progress = 50 ;     public RoundProgress(Context context) {         this(context, null );     }     public RoundProgress(Context context, AttributeSet attrs) {         this(context, attrs, 0 );     }     public RoundProgress(Context context, AttributeSet attrs, int defStyleAttr) {         super(context, attrs, defStyleAttr);         TypedArray mTypedArray = context.obtainStyledAttributes(attrs, R.styleable.RoundProgress);         //圆环的颜色         roundColor = mTypedArray.getColor(R.styleable.RoundProgress_roundColor, Color.RED);         //圆环进度的颜色         roundProgressColor = mTypedArray.getColor(R.styleable.RoundProgress_roundProgressColor, Color.GREEN);         //中间进度百分比文字字符串的颜色         textColor = mTypedArray.getColor(R.styleable.RoundProgress_textColor, Color.GREEN);         //中间进度百分比的字符串的字体大小         textSize = mTypedArray.getDimension(R.styleable.RoundProgress_textSize, 15 );         //圆环的宽度         roundWidth = mTypedArray.getDimension(R.styleable.RoundProgress_roundWidth, 5 );         mTypedArray.recycle();     }     @Override     protected void onDraw(Canvas canvas) {         //第一步:绘制一个最外层的圆         paint.setColor(roundColor);         paint.setStrokeWidth(roundWidth);         paint.setStyle(Paint.Style.STROKE);         paint.setAntiAlias(true);         int center = getWidth() / 2;         int radius = (int) (center - roundWidth / 2);         canvas.drawCircle(center, center, radius, paint);         //第二步:绘制正中间的文本         float textWidth = paint.measureText(progress + "%" );         paint.setColor(textColor);         paint.setTextSize(textSize);         paint.setStrokeWidth(0);         canvas.drawText(progress + "%", center - textWidth / 2, center + textSize / 2, paint);         //第三步:         /**          * 参数解释:          * oval:绘制弧形圈所包含的矩形范围轮廓          * 0:开始的角度          * 360 * progress / max:扫描过的角度          * false:是否包含圆心          * paint:绘制弧形时候的画笔          */         RectF oval = new RectF(center - radius, center - radius, center + radius, center + radius);         paint.setColor(roundProgressColor);         paint.setStrokeWidth(roundWidth);         paint.setStyle(Paint.Style.STROKE);         canvas.drawArc(oval, 0, 360 * progress / max, false, paint);     }     public void setProgress(int progress){         this.progress = progress;         if(progress>100){             this.progress = 100;         }         postInvalidate();     } }

  

?
1 2 3 4 5 6 7 8 9 10 <?xml version="1.0" encoding="utf-8"?> <resources>     <declare-styleable name="RoundProgress">         <attr name="roundColor" format="color" />         <attr name="roundProgressColor" format= "color"/>         <attr name="roundWidth" format="dimension" ></attr>         <attr name="textColor" format="color" />         <attr name="textSize" format="dimension" />     </declare-styleable> </resources>

  

?
1 2 3 4 5 6 7 8 9 10 11 <!-- 圆环进度-->               <cn.wh.ui.RoundProgress                   android:id="@+id/p_progresss"                   android:layout_width="120dp"                   android:layout_height="120dp"                   app:roundColor="@android:color/darker_gray"                   app:roundProgressColor="@android:color/holo_red_dark"                   app:roundWidth="10dp"                   app:textColor="#18b4ed"                   app:textSize="20sp">               </cn.wh.ui.RoundProgress>

  

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 private Runnable runnable = new Runnable() {        @Override        public void run() {            int tempProgress = 0 ;            try {                while (tempProgress <= totalProgress) {                    pProgresss.setProgress(tempProgress);                    tempProgress++;                    Thread.sleep(100 );                }            } catch (InterruptedException e) {                e.printStackTrace();            }        }    };