Android自定义控件:进度条的四种实现方式(Progress Wheel的解析)(源码 + Demo)

转载自:http://blog.csdn.net/u012403246/article/details/41477427?utm_source=tuicool&utm_medium=referral

Progress Wheel为GitHub热门项目,作者是:Todd-Davies,项目地址:

https://github.com/Todd-Davies/ProgressWheel


前三种实现方式代码出自:

http://stormzhang.com/openandroid/2013/11/15/android-custom-loading/


(源码在最后)


最近一直在学习自定义控件,搜了许多大牛们Blog里分享的小教程,也上GitHub找了一些类似的控件进行学习。发现读起来都不太好懂,就想写这么一篇东西作为学习笔记吧。


一、控件介绍:

进度条在App中非常常见,例如下载进度、加载图片、打开文章、打开网页等等……都需要这么一个效果让用户知道我们的App正在读取,以构造良好的交互。如果没有这样一个效果的话,用户没法知道东西有没有下载好、图片加载了没有、文章打开了没……会让用户很不爽。基于这样的情景我们的UI设计师们创造了这样一个控件。


二、这篇文章会涉及的知识点:

跟我一样刚入门的Android菜鸟们,我推荐大家先了解一下这些知识点再往下看。这些知识点我也会推荐一些博客给大家看看,更推荐大家看文档里的解释,当然大牛们可以直接无视……


1、ClipDrawable类:能够对一个drawable类进行剪切操作(即只显示某一部分的区域,另一部分隐藏),显示多大的区域由level控制(level取值是0~10000)

【博客:http://blog.csdn.net/lonelyroamer/article/details/8244777】、没文档的可以在这看【http://www.apihome.cn/api/android/ClipDrawable.html】


2、自定义View:guolin大神的深入学习View四部曲

Android LayoutInflater原理分析,带你一步步深入了解View——http://blog.csdn.net/guolin_blog/article/details/12921889】

Android视图绘制流程完全解析,带你一步步深入了解View——http://blog.csdn.net/guolin_blog/article/details/16330267】

Android视图状态及重绘流程分析,带你一步步深入了解View——http://blog.csdn.net/guolin_blog/article/details/17045157】

【Android自定义View的实现方法,带你一步步深入了解View——http://blog.csdn.net/guolin_blog/article/details/17357967】

3、没看过我写的:Android自定义控件——老版优酷三级菜单的话,或许需要看看这个:

【RotateAnimation详解——http://blog.csdn.net/u012403246/article/details/41415799】

三、Android上的实现方式:

(前三种方法比较简单,第四种方法是GitHub项目的解析,对前三种没兴趣可以直接跳到后边……)


1、效果图:


将进度条的变换过程分解为一帧一帧的图片,将这些一帧一帧的图片连起来构成一个动画。常用于:手机阅读网页、逛社区时,加载图片、文章等不需要清楚知道加载进度,但是需要知道是否进行加载的情景。


这种方法实现可以通过创建一个animation-list的XML文件,然后给系统API提供的ProgressBar的indeterminateDrawable属性就可以了。(这个属性应该是类似于设置一个动画吧……)


XML:

[html]  view plain  copy
 print ?
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <animation-list xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:oneshot="false" >  
  4.     <item android:duration="150" >  
  5.         <clip   
  6.             android:clipOrientation="horizontal"  
  7.             android:drawable="@drawable/loading_01"  
  8.             android:gravity="left"/>  
  9.     </item>  
  10.     <item android:duration="150" >  
  11.         <clip   
  12.             android:clipOrientation="horizontal"  
  13.             android:drawable="@drawable/loading_02"  
  14.             android:gravity="left"/>  
  15.     </item>  
  16.     <item android:duration="150" >  
  17.         <clip   
  18.             android:clipOrientation="horizontal"  
  19.             android:drawable="@drawable/loading_03"  
  20.             android:gravity="left"/>  
  21.     </item>  
  22.     <item android:duration="150" >  
  23.         <clip   
  24.             android:clipOrientation="horizontal"  
  25.             android:drawable="@drawable/loading_04"  
  26.             android:gravity="left"/>  
  27.     </item>  
  28.     <item android:duration="150" >  
  29.         <clip   
  30.             android:clipOrientation="horizontal"  
  31.             android:drawable="@drawable/loading_05"  
  32.             android:gravity="left"/>  
  33.     </item>  
  34.     <item android:duration="150" >  
  35.         <clip   
  36.             android:clipOrientation="horizontal"  
  37.             android:drawable="@drawable/loading_06"  
  38.             android:gravity="left"/>  
  39.     </item>  
  40.     <item android:duration="150" >  
  41.         <clip   
  42.             android:clipOrientation="horizontal"  
  43.             android:drawable="@drawable/loading_07"  
  44.             android:gravity="left"/>  
  45.     </item>  
  46.     <item android:duration="150" >  
  47.         <clip   
  48.             android:clipOrientation="horizontal"  
  49.             android:drawable="@drawable/loading_08"  
  50.             android:gravity="left"/>  
  51.     </item>  
  52.     <item android:duration="150" >  
  53.         <clip   
  54.             android:clipOrientation="horizontal"  
  55.             android:drawable="@drawable/loading_09"  
  56.             android:gravity="left"/>  
  57.     </item>  
  58.     <item android:duration="150" >  
  59.         <clip   
  60.             android:clipOrientation="horizontal"  
  61.             android:drawable="@drawable/loading_10"  
  62.             android:gravity="left"/>  
  63.     </item>  
  64.     <item android:duration="150" >  
  65.         <clip   
  66.             android:clipOrientation="horizontal"  
  67.             android:drawable="@drawable/loading_11"  
  68.             android:gravity="left"/>  
  69.     </item>  
  70.     <item android:duration="150" >  
  71.         <clip   
  72.             android:clipOrientation="horizontal"  
  73.             android:drawable="@drawable/loading_12"  
  74.             android:gravity="left"/>  
  75.     </item>  
  76.   
  77. </animation-list>  

[html]  view plain  copy
 print ?
  1. <ProgressBar   
  2.     android:layout_width="wrap_content"  
  3.     android:layout_height="wrap_content"  
  4.     android:indeterminateDrawable="@drawable/progressbar1"  
  5.     />  

2、效果图:

在上一篇有关自定义控件的博客里我们使用了一个RotateAnimation类来实现旋转效果 (http://blog.csdn.net/u012403246/article/details/41309161),其实,我们在这里也可以把一张图片,通过旋转,达到我们要的效果。本质上和上一种方法没多大区别。


我们只需要创建一个rotate的XML,对其属性进行一些简单的设置,然后加入我们要用的图片就可以了。


XML:

[html]  view plain  copy
 print ?
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <rotate xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:pivotX="50%"  
  4.     android:pivotY="50%"  
  5.     android:fromDegrees="0"  
  6.     android:toDegrees="360"  
  7.     android:interpolator="@android:anim/accelerate_decelerate_interpolator" >  
  8.     <bitmap   
  9.         android:antialias="true"  
  10.         android:filter="true"  
  11.         android:src="@drawable/loading_360"/>  
  12.   
  13. </rotate>  

[html]  view plain  copy
 print ?
  1. <ProgressBar   
  2.     android:layout_width="wrap_content"  
  3.     android:layout_height="wrap_content"  
  4.     android:indeterminateDrawable="@drawable/progressbar2"/>  

3、效果图:

我们可以弄两张照片,第一张是纯黑色的,然后把这张照片中心挖一个圆出来,圆区域弄成白色,挖出来的圆弄成第二张照片。我们不妨叠加显示两张照片,刚开始把第二张完全“遮住”,随着加载进度的增加,我们减少遮住的区域把第二张照片慢慢的显示出来。


Android上刚好就有这么一个ClipDrawable类,能够实现剪裁的过程。我们来看看怎么通过这样的方式自定义一个进度条控件。


代码:

[java]  view plain  copy
 print ?
  1. public class MyProgressBar extends FrameLayout{  
  2.     private boolean running;  
  3.     private int progress = 0;  
  4.     private static final int MAX_PROGRESS = 10000;  
  5.       
  6.     private ClipDrawable clip;  
  7.       
  8.     private Handler handler = new Handler(){  
  9.         @Override  
  10.         public void handleMessage(android.os.Message msg) {  
  11.             if(msg.what == 0x123)  
  12.                 clip.setLevel(progress);  
  13.         }  
  14.     };  
  15.       
  16.     public MyProgressBar(Context context){  
  17.         this(context,null,0);  
  18.     }  
  19.   
  20.     public MyProgressBar(Context context,AttributeSet attrs){  
  21.         this(context,null,0);  
  22.     }  
  23.       
  24.     public MyProgressBar(Context context, AttributeSet attrs, int defStyle) {  
  25.         super(context, attrs, defStyle);  
  26.         Init(context);  
  27.     }  
  28.       
  29.     public void Init(Context context){  
  30.         View view = LayoutInflater.from(context).inflate(R.layout.view, null);  
  31.           
  32.         ImageView iv = (ImageView)view.findViewById(R.id.progress_img);  
  33.           
  34.         addView(view);  
  35.         clip = (ClipDrawable)iv.getDrawable();  
  36.           
  37.         Thread thread = new Thread(new Runnable() {  
  38.               
  39.             @Override  
  40.             public void run() {  
  41.                 running = true;  
  42.                 while(running){  
  43.                     handler.sendEmptyMessage(0x123);  
  44.                     if(progress == MAX_PROGRESS)  
  45.                         progress = 0;  
  46.                     progress += 100;  
  47.                     try {  
  48.                         Thread.sleep(18);  
  49.                     } catch (InterruptedException e) {  
  50.                         e.printStackTrace();  
  51.                     }  
  52.                 }  
  53.             }  
  54.         });  
  55.         thread.start();  
  56.     }  
  57.   
  58.     public void stop(){  
  59.         progress = 0;  
  60.         running = false;  
  61.     }  
  62. }  
通过代码我们可以看到,逻辑非常简单,关键就在于ClipDrawable的setLevel()方法,这个是设置剪裁效果的。


4、效果图:

实现一个View的子类——Progress Wheel类,实现进度条效果。具体的内容我都写在了注释上,如果不了解自定义控件的知识,可以去阅读guolin博客里自定义View四部曲的讲解,讲的挺好的。


代码

[java]  view plain  copy
 print ?
  1. public class ProgressWheel extends View {  
  2.   
  3.     //绘制View用到的各种长、宽带大小  
  4.     private int layout_height = 0;  
  5.     private int layout_width = 0;  
  6.     private int fullRadius = 100;  
  7.     private int circleRadius = 80;  
  8.     private int barLength = 60;  
  9.     private int barWidth = 20;  
  10.     private int rimWidth = 20;  
  11.     private int textSize = 20;  
  12.     private float contourSize = 0;  
  13.   
  14.     //与页边的间距  
  15.     private int paddingTop = 5;  
  16.     private int paddingBottom = 5;  
  17.     private int paddingLeft = 5;  
  18.     private int paddingRight = 5;  
  19.   
  20.     //View要绘制的颜色  
  21.     private int barColor = 0xAA000000;  
  22.     private int contourColor = 0xAA000000;  
  23.     private int circleColor = 0x00000000;  
  24.     private int rimColor = 0xAADDDDDD;  
  25.     private int textColor = 0xFF000000;  
  26.   
  27.     //绘制要用的画笔  
  28.     private Paint barPaint = new Paint();  
  29.     private Paint circlePaint = new Paint();  
  30.     private Paint rimPaint = new Paint();  
  31.     private Paint textPaint = new Paint();  
  32.     private Paint contourPaint = new Paint();  
  33.   
  34.     //绘制要用的矩形  
  35.     @SuppressWarnings("unused")  
  36.     private RectF rectBounds = new RectF();  
  37.     private RectF circleBounds = new RectF();  
  38.     private RectF circleOuterContour = new RectF();  
  39.     private RectF circleInnerContour = new RectF();  
  40.   
  41.     //动画  
  42.     //每次绘制要移动的像素数目  
  43.     private int spinSpeed = 2;  
  44.     //绘制过程的时间间隔  
  45.     private int delayMillis = 0;  
  46.     int progress = 0;  
  47.     boolean isSpinning = false;  
  48.   
  49.     //其他  
  50.     private String text = "";  
  51.     private String[] splitText = {};  
  52.   
  53.     /** 
  54.      * ProgressWheel的构造方法 
  55.      * 
  56.      * @param context 
  57.      * @param attrs 
  58.      */  
  59.     public ProgressWheel(Context context, AttributeSet attrs) {  
  60.         super(context, attrs);  
  61.   
  62.         parseAttributes(context.obtainStyledAttributes(attrs,  
  63.                 R.styleable.ProgressWheel));  
  64.     }  
  65.   
  66.     //----------------------------------  
  67.     //初始化一些元素  
  68.     //----------------------------------  
  69.   
  70.     /* 
  71.      * 调用这个方法时,使View绘制为方形 
  72.      * From: http://www.jayway.com/2012/12/12/creating-custom-android-views-part-4-measuring-and-how-to-force-a-view-to-be-square/ 
  73.      *  
  74.      */  
  75.     @Override  
  76.     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {  
  77.         // 首先我们要调用超类的onMeasure借口   
  78.         // 原因是我们自己去实现一个方法获得长度、宽度太麻烦了  
  79.         // 使用超类的的方法非常方便而且让复杂的细节可控  
  80.         super.onMeasure(widthMeasureSpec, heightMeasureSpec);  
  81.   
  82.         // 在这里我们不能使用getWidth()和getHeight()。   
  83.         // 因为这两个方法只能在View的布局完成后才能使用,而一个View的绘制过程是先绘制元素,再绘制Layout  
  84.         // 所以我们必须使用getMeasuredWidth()和getMeasuredHeight()  
  85.         int size = 0;  
  86.         int width = getMeasuredWidth();  
  87.         int height = getMeasuredHeight();  
  88.         int widthWithoutPadding = width - getPaddingLeft() - getPaddingRight();  
  89.         int heigthWithoutPadding = height - getPaddingTop() - getPaddingBottom();  
  90.           
  91.         // 最后我们用一些简单的逻辑去计算View的大小并调用setMeasuredDimension()去设置View的大小  
  92.         // 在比较View的长宽前我们不考虑间距,但当我们设置View所需要绘制的面积时,我们要考虑它  
  93.         // 不考虑间距的View(View内的实际画面)此时就应该是方形的,但是由于间距的存在,最终View所占的面积可能不是方形的   
  94.         if (widthWithoutPadding > heigthWithoutPadding) {  
  95.             size = heigthWithoutPadding;  
  96.         } else {  
  97.             size = widthWithoutPadding;  
  98.         }  
  99.           
  100.         // 如果你重写了onMeasure()方法,你必须调用setMeasuredDimension()方法   
  101.         // 这是你设置View大小的唯一途径    
  102.         // 如果你不调用setMeasuredDimension()方法,父控件会抛出异常,并且程序会崩溃  
  103.         // 如果我们使用了超类的onMeasure()方法,我们就不是那么需要setMeasuredDimension()方法  
  104.         // 然而,重写onMeasure()方法是为了改变既有的绘制流程,所以我们必须调用setMeasuredDimension()方法以达到我们的目的  
  105.         setMeasuredDimension(size + getPaddingLeft() + getPaddingRight(), size + getPaddingTop() + getPaddingBottom());  
  106.     }  
  107.   
  108.     /** 
  109.      * 使用onSizeChanged方法代替onAttachedToWindow获得View的面积 
  110.      * 因为这个方法会在测量了MATCH_PARENT和WRAP_CONTENT后马上被调用 
  111.      * 使用获得的面积设置View 
  112.      */  
  113.     @Override  
  114.     protected void onSizeChanged(int w, int h, int oldw, int oldh) {  
  115.         super.onSizeChanged(w, h, oldw, oldh);  
  116.   
  117.         // Share the dimensions  
  118.         layout_width = w;  
  119.         layout_height = h;  
  120.   
  121.         setupBounds();  
  122.         setupPaints();  
  123.         invalidate();  
  124.     }  
  125.   
  126.     /** 
  127.      * 设置我们想要绘制的progress wheel的颜色 
  128.      */  
  129.     private void setupPaints() {  
  130.         barPaint.setColor(barColor);  
  131.         barPaint.setAntiAlias(true);  
  132.         barPaint.setStyle(Style.STROKE);  
  133.         barPaint.setStrokeWidth(barWidth);  
  134.   
  135.         rimPaint.setColor(rimColor);  
  136.         rimPaint.setAntiAlias(true);  
  137.         rimPaint.setStyle(Style.STROKE);  
  138.         rimPaint.setStrokeWidth(rimWidth);  
  139.   
  140.         circlePaint.setColor(circleColor);  
  141.         circlePaint.setAntiAlias(true);  
  142.         circlePaint.setStyle(Style.FILL);  
  143.   
  144.         textPaint.setColor(textColor);  
  145.         textPaint.setStyle(Style.FILL);  
  146.         textPaint.setAntiAlias(true);  
  147.         textPaint.setTextSize(textSize);  
  148.   
  149.         contourPaint.setColor(contourColor);  
  150.         contourPaint.setAntiAlias(true);  
  151.         contourPaint.setStyle(Style.STROKE);  
  152.         contourPaint.setStrokeWidth(contourSize);  
  153.     }  
  154.   
  155.     /** 
  156.      * 设置元素的边界 
  157.      */  
  158.     private void setupBounds() {  
  159.         // 为了保持宽度和长度的一致,我们要获得layout_width和layout_height中较小的一个,从而绘制一个圆  
  160.         int minValue = Math.min(layout_width, layout_height);  
  161.   
  162.         // 计算在绘制过程中在x,y方向的偏移量  
  163.         int xOffset = layout_width - minValue;  
  164.         int yOffset = layout_height - minValue;  
  165.   
  166.         // 间距加上偏移量  
  167.         paddingTop = this.getPaddingTop() + (yOffset / 2);  
  168.         paddingBottom = this.getPaddingBottom() + (yOffset / 2);  
  169.         paddingLeft = this.getPaddingLeft() + (xOffset / 2);  
  170.         paddingRight = this.getPaddingRight() + (xOffset / 2);  
  171.   
  172.         int width = getWidth(); //this.getLayoutParams().width;  
  173.         int height = getHeight(); //this.getLayoutParams().height;  
  174.   
  175.         rectBounds = new RectF(paddingLeft,  
  176.                 paddingTop,  
  177.                 width - paddingRight,  
  178.                 height - paddingBottom);  
  179.   
  180.         circleBounds = new RectF(paddingLeft + barWidth,  
  181.                 paddingTop + barWidth,  
  182.                 width - paddingRight - barWidth,  
  183.                 height - paddingBottom - barWidth);  
  184.         circleInnerContour = new RectF(circleBounds.left + (rimWidth / 2.0f) + (contourSize / 2.0f), circleBounds.top + (rimWidth / 2.0f) + (contourSize / 2.0f), circleBounds.right - (rimWidth / 2.0f) - (contourSize / 2.0f), circleBounds.bottom - (rimWidth / 2.0f) - (contourSize / 2.0f));  
  185.         circleOuterContour = new RectF(circleBounds.left - (rimWidth / 2.0f) - (contourSize / 2.0f), circleBounds.top - (rimWidth / 2.0f) - (contourSize / 2.0f), circleBounds.right + (rimWidth / 2.0f) + (contourSize / 2.0f), circleBounds.bottom + (rimWidth / 2.0f) + (contourSize / 2.0f));  
  186.   
  187.         fullRadius = (width - paddingRight - barWidth) / 2;  
  188.         circleRadius = (fullRadius - barWidth) + 1;  
  189.     }  
  190.   
  191.     /** 
  192.      * 从XML中解析控件的属性 
  193.      * 
  194.      * @param a the attributes to parse 
  195.      */  
  196.     private void parseAttributes(TypedArray a) {  
  197.         barWidth = (int) a.getDimension(R.styleable.ProgressWheel_barWidth,  
  198.                 barWidth);  
  199.   
  200.         rimWidth = (int) a.getDimension(R.styleable.ProgressWheel_rimWidth,  
  201.                 rimWidth);  
  202.   
  203.         spinSpeed = (int) a.getDimension(R.styleable.ProgressWheel_spinSpeed,  
  204.                 spinSpeed);  
  205.   
  206.         delayMillis = a.getInteger(R.styleable.ProgressWheel_delayMillis,  
  207.                 delayMillis);  
  208.         if (delayMillis < 0) {  
  209.             delayMillis = 0;  
  210.         }  
  211.   
  212.         barColor = a.getColor(R.styleable.ProgressWheel_barColor, barColor);  
  213.   
  214.         barLength = (int) a.getDimension(R.styleable.ProgressWheel_barLength,  
  215.                 barLength);  
  216.   
  217.         textSize = (int) a.getDimension(R.styleable.ProgressWheel_textSize,  
  218.                 textSize);  
  219.   
  220.         textColor = (int) a.getColor(R.styleable.ProgressWheel_textColor,  
  221.                 textColor);  
  222.   
  223.         //如果text是空的,就无视它  
  224.         if (a.hasValue(R.styleable.ProgressWheel_text)) {  
  225.             setText(a.getString(R.styleable.ProgressWheel_text));  
  226.         }  
  227.   
  228.         rimColor = (int) a.getColor(R.styleable.ProgressWheel_rimColor,  
  229.                 rimColor);  
  230.   
  231.         circleColor = (int) a.getColor(R.styleable.ProgressWheel_circleColor,  
  232.                 circleColor);  
  233.   
  234.         contourColor = a.getColor(R.styleable.ProgressWheel_contourColor, contourColor);  
  235.         contourSize = a.getDimension(R.styleable.ProgressWheel_contourSize, contourSize);  
  236.   
  237.   
  238.         // 使用TypedArray获得控件属性时必须要注意:使用结束后必须回收TypedArray的对象  
  239.         a.recycle();  
  240.     }  
  241.   
  242.     //----------------------------------  
  243.     //动画  
  244.     //----------------------------------  
  245.   
  246.     protected void onDraw(Canvas canvas) {  
  247.         super.onDraw(canvas);  
  248.         //绘制内圆  
  249.         canvas.drawArc(circleBounds, 360360false, circlePaint);  
  250.         //绘制边界  
  251.         canvas.drawArc(circleBounds, 360360false, rimPaint);  
  252.         canvas.drawArc(circleOuterContour, 360360false, contourPaint);  
  253.         canvas.drawArc(circleInnerContour, 360360false, contourPaint);  
  254.         //绘制条纹  
  255.         if (isSpinning) {  
  256.             canvas.drawArc(circleBounds, progress - 90, barLength, false,  
  257.                     barPaint);  
  258.         } else {  
  259.             canvas.drawArc(circleBounds, -90, progress, false, barPaint);  
  260.         }  
  261.         //绘制我们想要设置的文字 (并让它显示在圆水平和垂直方向的中心处)  
  262.         float textHeight = textPaint.descent() - textPaint.ascent();  
  263.         float verticalTextOffset = (textHeight / 2) - textPaint.descent();  
  264.   
  265.         for (String s : splitText) {  
  266.             float horizontalTextOffset = textPaint.measureText(s) / 2;  
  267.             canvas.drawText(s, this.getWidth() / 2 - horizontalTextOffset,  
  268.                     this.getHeight() / 2 + verticalTextOffset, textPaint);  
  269.         }  
  270.         if (isSpinning) {  
  271.             scheduleRedraw();  
  272.         }  
  273.     }  
  274.   
  275.     private void scheduleRedraw() {  
  276.         progress += spinSpeed;  
  277.         if (progress > 360) {  
  278.             progress = 0;  
  279.         }  
  280.         postInvalidateDelayed(delayMillis);  
  281.     }  
  282.   
  283.     /** 
  284.     *   判断wheel是否在旋转 
  285.     */  
  286.       
  287.     public boolean isSpinning() {  
  288.         if(isSpinning){  
  289.             return true;  
  290.         } else {  
  291.             return false;  
  292.         }  
  293.     }  
  294.       
  295.     /** 
  296.      * 重设进度条的值 
  297.      */  
  298.     public void resetCount() {  
  299.         progress = 0;  
  300.         setText("0%");  
  301.         invalidate();  
  302.     }  
  303.   
  304.     /** 
  305.      * 停止进度条的旋转 
  306.      */  
  307.     public void stopSpinning() {  
  308.         isSpinning = false;  
  309.         progress = 0;  
  310.         postInvalidate();  
  311.     }  
  312.   
  313.   
  314.     /** 
  315.      * 让进度条开启旋转模式 
  316.      */  
  317.     public void spin() {  
  318.         isSpinning = true;  
  319.         postInvalidate();  
  320.     }  
  321.   
  322.     /** 
  323.      * 让进度条每次增加1(最大值为360) 
  324.      */  
  325.     public void incrementProgress() {  
  326.         isSpinning = false;  
  327.         progress++;  
  328.         if (progress > 360)  
  329.             progress = 0;  
  330.         setText(Math.round(((float) progress / 360) * 100) + "%");  
  331.        postInvalidate();  
  332.     }  
  333.   
  334.   
  335.     /** 
  336.      * 设置进度条为一个确切的数值 
  337.      */  
  338.     public void setProgress(int i) {  
  339.         isSpinning = false;  
  340.         progress = i;  
  341.         postInvalidate();  
  342.     }  
  343.   
  344.     //----------------------------------  
  345.     //get和set方法  
  346.     //----------------------------------  
  347.   
  348.     /** 
  349.      * 设置progress bar的文字并不需要刷新View 
  350.      * 
  351.      * @param text the text to show ('\n' constitutes a new line) 
  352.      */  
  353.     public void setText(String text) {  
  354.         this.text = text;  
  355.         splitText = this.text.split("\n");  
  356.     }  
  357.   
  358.     public int getCircleRadius() {  
  359.         return circleRadius;  
  360.     }  
  361.   
  362.     public void setCircleRadius(int circleRadius) {  
  363.         this.circleRadius = circleRadius;  
  364.     }  
  365.   
  366.     public int getBarLength() {  
  367.         return barLength;  
  368.     }  
  369.   
  370.     public void setBarLength(int barLength) {  
  371.         this.barLength = barLength;  
  372.     }  
  373.   
  374.     public int getBarWidth() {  
  375.         return barWidth;  
  376.     }  
  377.   
  378.     public void setBarWidth(int barWidth) {  
  379.         this.barWidth = barWidth;  
  380.           
  381.         if ( this.barPaint != null ) {  
  382.             this.barPaint.setStrokeWidth( this.barWidth );  
  383.         }  
  384.     }  
  385.   
  386.     public int getTextSize() {  
  387.         return textSize;  
  388.     }  
  389.   
  390.     public void setTextSize(int textSize) {  
  391.         this.textSize = textSize;  
  392.           
  393.         if ( this.textPaint != null ) {  
  394.             this.textPaint.setTextSize( this.textSize );  
  395.         }  
  396.     }  
  397.   
  398.     public int getPaddingTop() {  
  399.         return paddingTop;  
  400.     }  
  401.   
  402.     public void setPaddingTop(int paddingTop) {  
  403.         this.paddingTop = paddingTop;  
  404.     }  
  405.   
  406.     public int getPaddingBottom() {  
  407.         return paddingBottom;  
  408.     }  
  409.   
  410.     public void setPaddingBottom(int paddingBottom) {  
  411.         this.paddingBottom = paddingBottom;  
  412.     }  
  413.   
  414.     public int getPaddingLeft() {  
  415.         return paddingLeft;  
  416.     }  
  417.   
  418.     public void setPaddingLeft(int paddingLeft) {  
  419.         this.paddingLeft = paddingLeft;  
  420.     }  
  421.   
  422.     public int getPaddingRight() {  
  423.         return paddingRight;  
  424.     }  
  425.   
  426.     public void setPaddingRight(int paddingRight) {  
  427.         this.paddingRight = paddingRight;  
  428.     }  
  429.   
  430.     public int getBarColor() {  
  431.         return barColor;  
  432.     }  
  433.   
  434.     public void setBarColor(int barColor) {  
  435.         this.barColor = barColor;  
  436.           
  437.         if ( this.barPaint != null ) {  
  438.             this.barPaint.setColor( this.barColor );  
  439.         }  
  440.     }  
  441.   
  442.     public int getCircleColor() {  
  443.         return circleColor;  
  444.     }  
  445.   
  446.     public void setCircleColor(int circleColor) {  
  447.         this.circleColor = circleColor;  
  448.           
  449.         if ( this.circlePaint != null ) {  
  450.             this.circlePaint.setColor( this.circleColor);  
  451.         }  
  452.     }  
  453.   
  454.     public int getRimColor() {  
  455.         return rimColor;  
  456.     }  
  457.   
  458.     public void setRimColor(int rimColor) {  
  459.         this.rimColor = rimColor;  
  460.           
  461.         if ( this.rimPaint != null ) {  
  462.             this.rimPaint.setColor( this.rimColor );  
  463.         }  
  464.     }  
  465.   
  466.   
  467.     public Shader getRimShader() {  
  468.         return rimPaint.getShader();  
  469.     }  
  470.   
  471.     public void setRimShader(Shader shader) {  
  472.         this.rimPaint.setShader(shader);  
  473.     }  
  474.   
  475.     public int getTextColor() {  
  476.         return textColor;  
  477.     }  
  478.   
  479.     public void setTextColor(int textColor) {  
  480.         this.textColor = textColor;  
  481.           
  482.         if ( this.textPaint != null ) {  
  483.             this.textPaint.setColor( this.textColor );  
  484.         }  
  485.     }  
  486.   
  487.     public int getSpinSpeed() {  
  488.         return spinSpeed;  
  489.     }  
  490.   
  491.     public void setSpinSpeed(int spinSpeed) {  
  492.         this.spinSpeed = spinSpeed;  
  493.     }  
  494.   
  495.     public int getRimWidth() {  
  496.         return rimWidth;  
  497.     }  
  498.   
  499.     public void setRimWidth(int rimWidth) {  
  500.         this.rimWidth = rimWidth;  
  501.           
  502.         if ( this.rimPaint != null ) {  
  503.             this.rimPaint.setStrokeWidth( this.rimWidth );  
  504.         }  
  505.     }  
  506.   
  507.     public int getDelayMillis() {  
  508.         return delayMillis;  
  509.     }  
  510.   
  511.     public void setDelayMillis(int delayMillis) {  
  512.         this.delayMillis = delayMillis;  
  513.     }  
  514.       
  515.     public int getContourColor() {  
  516.         return contourColor;  
  517.     }  
  518.       
  519.     public void setContourColor(int contourColor) {  
  520.         this.contourColor = contourColor;  
  521.           
  522.         if ( contourPaint != null ) {  
  523.             this.contourPaint.setColor( this.contourColor );  
  524.         }  
  525.     }  
  526.       
  527.     public float getContourSize() {  
  528.         return this.contourSize;  
  529.     }  
  530.       
  531.     public void setContourSize(float contourSize) {  
  532.         this.contourSize = contourSize;  
  533.           
  534.         if ( contourPaint != null ) {  
  535.             this.contourPaint.setStrokeWidth( this.contourSize );  
  536.         }  
  537.     }  
  538. }  

源码下载

你可能感兴趣的:(android,自定义,progres)