自定义实现圆形播放进度条(Android,飞一般的感觉)。

废话不多说,先上效果图:


android 圆形等待动画 android圆形进度条_android

Android提供了很多基本的控件实现,但不是一个完整、强大的实现。

幸运的是,Android提供了自定义控件的实现,有了自定义控件,我们就可以再Android的基础控件上实现我们想要的功能或者自定义的外观。

以ProgressBar为例,对于可调节的进度条似乎只有长条形的ProgressBar(圆形的都是不停转动的那种)

假如我们想要一个可调节进度的圆形进度条呢。。。

Ok,下面我们直接切入主题(关于自定义控件的相关实现细节就不多说了,还不太清楚的童鞋先找相关资料补习一下)

该自定义控件的实现思路是继承自View,然后重写onDraw

先看看该类有哪些成员变量:

1. public class CircleProgress extends
2.   
3.       
4. private  static final int DEFAULT_MAX_VALUE = 100;         // 默认进度条最大值 
5. private  static final int DEFAULT_PAINT_WIDTH = 10;            // 默认画笔宽度 
6. private  static final int DEFAULT_PAINT_COLOR = 0xffffcc00;        // 默认画笔颜色 
7. private  static final boolean DEFAULT_FILL_MODE = true;        // 默认填充模式 
8. private  static final int DEFAULT_INSIDE_VALUE = 0;            // 默认缩进距离 
9.       
10.       
11. private CircleAttribute mCircleAttribute;              // 圆形进度条基本属性 
12.   
13. private int mMaxProgress;                      // 进度条最大值                                                                                                                        
14. private int mMainCurProgress;                      // 主进度条当前值  
15. private int mSubCurProgress;                       // 子进度条当前值  
16.       
17. private CartoomEngine mCartoomEngine;                  // 动画引擎 
18.       
19. private Drawable mBackgroundPicture;                   // 背景图
  
 
1. class
2.     {  
3. public RectF   mRoundOval;             // 圆形所在矩形区域 
4. public boolean mBRoundPaintsFill;          // 是否填充以填充模式绘制圆形 
5. public int     mSidePaintInterval;         // 圆形向里缩进的距离 
6. public int     mPaintWidth;                // 圆形画笔宽度(填充模式下无视) 
7. public int     mPaintColor;                // 画笔颜色  (即主进度条画笔颜色,子进度条画笔颜色为其半透明值)  
8. public int     mDrawPos;               // 绘制圆形的起点(默认为-90度即12点钟方向) 
9.            
10. public Paint   mMainPaints;                // 主进度条画笔        
11. public Paint   mSubPaint;                  // 子进度条画笔  
12.            
13. public Paint   mBottomPaint;               // 无背景图时绘制所用画笔
 
  
 
1. class
2. {  
3. public
4. public boolean mBCartoom;               // 是否正在作动画  
5. public Timer   mTimer;                  // 用于作动画的TIMER  
6. public       MyTimerTask    mTimerTask;     // 动画任务 
7. public int   mSaveMax;              // 在作动画时会临时改变MAX值,该变量用于保存值以便恢复    
8. public int     mTimerInterval;              // 定时器触发间隔时间(ms)      
9. public float   mCurFloatProcess;            // 作动画时当前进度值 
 
 下面看看onDraw的代码片段:
 
1. public void
2. // TODO Auto-generated method stub 
3. super.onDraw(canvas);  
4.                   
5. if (mBackgroundPicture == null)                                 // 没背景图的话就绘制底色 
6.         {  
7. 0, 360, mCircleAttribute.mBRoundPaintsFill, mCircleAttribute.mBottomPaint);  
8.         }  
9.           
10.           
11. float subRate = (float)mSubCurProgress / mMaxProgress;  
12. float subSweep = 360
13.         canvas.drawArc(mCircleAttribute.mRoundOval, mCircleAttribute.mDrawPos, subSweep, mCircleAttribute.mBRoundPaintsFill, mCircleAttribute.mSubPaint);  
14.           
15. float rate = (float)mMainCurProgress / mMaxProgress;  
16. float sweep = 360
17.         canvas.drawArc(mCircleAttribute.mRoundOval, mCircleAttribute.mDrawPos, sweep, mCircleAttribute.mBRoundPaintsFill, mCircleAttribute.mMainPaints);  
18.       
19.       
20.     }  
 
 canvas的drawArc(RectF oval, float startAngle, float sweepAngle, boolean useCenter, Paint paint) 方法是关键
 相关参数说明大家详看SDK文档 控件大小决定oval
 画笔属性设置paint
 useCenter表示是否填充
 startAngle是绘制圆弧的起点,我们使用-90度,即12点钟方向
 sweepAngle是从起点顺时针绘制覆盖的角度,意味着进度值为30%的话,就是 360 * 30% 设置进度的代码片段:
1. public synchronized void setMainProgress (int
2.  {  
3.         mMainCurProgress = progress;  
4. if (mMainCurProgress < 0)  
5.         {  
6. 0;  
7.         }  
8.           
9. if
10.         {  
11.             mMainCurProgress = mMaxProgress;  
12.         }  
13.           
14.         invalidate();  
15. }  
 设置进度值之后触发重绘,计算sweepAngle的值,最后完成绘制效果,怎么样,是不是就对上了
  
 该控件的自定义属性如下: 
1. <?xml version="1.0" encoding="utf-8"?>    
2. lt;resources>   
3.   
4. "CircleProgressBar">    
5. "max" format="integer"/>                <!-- 进度条最大值 -->  
6. "fill" format="boolean"/>           <!-- 是否填充圆形区域 -->  
7. "Paint_Width" format="integer"/>        <!-- 画笔宽度,填充模式下无效,会被重置为0
8. "Paint_Color" format="integer"/>        <!-- 画笔颜色 -->  
9. "Inside_Interval" format="integer"/> <!-- 圆形区域向里缩进的距离 -->   
10.    </declare-styleable>    
11.      
12. lt;/resources>   
 
 再贴上本例的布局文件:
 
1. <?xml version="1.0" encoding="utf-8"?>  
2. <LinearLayout xmlns:Android="http://schemas.android.com/apk/res/android"
3. "http://schemas.android.com/apk/res/com.genius.progress"
4. "fill_parent"
5. "fill_parent"
6. "vertical"
7. "#ffffff">  
8.   
9.       
10.     <LinearLayout   
11. "wrap_content"
12. "match_parent"
13. "@+id/linearLayout1"
14. "horizontal"
15. "center_horizontal">  
16.       
17.         <Button   
18. "增加主进度条"
19. "@+id/buttonAddMainPro"
20. "wrap_content"
21. "wrap_content"
22. "1">  
23.         </Button>  
24.           
25.           
26.         <Button   
27. "增加子进度条"
28. "@+id/buttonAddSubPro"
29. "wrap_content"
30. "wrap_content"
31. "1">  
32.         </Button>   
33.           
34.         <ImageButton  
35. "@+id/buttonImage"
36. "wrap_content"
37. "wrap_content"
38. "@drawable/background2"
39. "1"
40.           
41.     </LinearLayout>  
42.       
43.           
44.     <LinearLayout   
45. "wrap_content"
46. "match_parent"
47. "@+id/linearLayout2"
48. "horizontal"
49. "#ff0000"
50. "center_horizontal">  
51.        
52.        
53.         <com.genius.circle.CircleProgress  
54. "@+id/roundBar1"
55. "wrap_content"
56. "wrap_content"
57. "@drawable/background1"
58. "100"
59. "false"
60. "5"
61. "4"
62. "0xff0000ff"
63.         />  
64.       
65.           
66.         <com.genius.circle.CircleProgress   
67. "@+id/roundBar2"
68. "wrap_content"
69. "wrap_content"
70. "@drawable/background3"
71. "100"
72. "8"
73. "true"
74. "4"
75. "0xffaa5500"
76.         />  
77.        
78.           
79.         <com.genius.circle.CircleProgress   
80. "@+id/roundBar3"
81. "96dp"
82. "96dp"
83. "100"
84. "false"
85. "40"
86. "20"
87.         />  
88.           
89.     </LinearLayout>  
90.   
91.        
92.       
93.        
94.     <LinearLayout   
95. "wrap_content"
96. "match_parent"
97. "@+id/linearLayout3"
98. "horizontal"
99. "center_horizontal|center_vertical"
100. "#00ff00">    
101.       
102.       
103.             <Button   
104. "启动动画"
105. "@+id/buttonStart"
106. "100dip"
107. "wrap_content">  
108.             </Button>  
109.       
110.       
111.             <com.genius.circle.CircleProgress   
112. "@+id/roundBar4"
113. "wrap_content"
114. "wrap_content"
115. "@drawable/background1"
116. "6"
117. "0xff0000ff"
118.             />  
119.           
120.             <Button   
121. "停止动画"
122. "@+id/buttonStop"
123. "100dip"
124. "wrap_content">  
125.             </Button>  
126.       
127.       
128.     </LinearLayout>  
129.       
130.       
131.   
132. </LinearLayout>


大家比对下效果图就明白了

此外该控件中有两个接口是作动画相关的

public synchronized void  startCartoom(int time)

public synchronized void  stopCartoom()

比如你想播放一个10秒的声音片段,同时用进度条来表示播放进度,那么直接调用 startCartoom(10)来开启动画即可

其他的似乎没啥好说的了,源码工程里的注释也写很清楚了,有兴趣的童鞋下下来看看就明白了