Android的自定义的环形进度条实现有多种方法。以下是其中一个,可以实现一些复杂点的效果。
实现思路:继承View类,并重写onDraw方法。同时用一个类实时计算绘画的进度,实现环形进度条的效果。
实现出来的效果:
- 添加了监听接口,监控进度条的绘画是否完成,即进度是100%。
- 可以设定进度条播放的时间
- 可以点击暂停和继续还有停止进行进度条的绘画,可以当实时显示音乐当前播放进度的按钮。
- 更多的效果可有待继续增加
效果图:
xml文件中的属性设置:
1 <!-- 环形进度条按钮属性 -->
2 <declare-styleable name="CircleProgressBar">
3 <attr name="max" format="integer"/> <!-- 进度条最大值 -->
4 <attr name="fill" format="boolean"/> <!-- 是否填充圆形区域 ,不填充就是环形的进度条了-->
5 <attr name="Paint_Width" format="integer"/> <!-- 画笔宽度,填充模式下无效,会被重置为0 -->
6 <attr name="Paint_Color" format="integer"/> <!-- 画笔颜色 -->
7 <attr name="Inside_Interval" format="integer"/> <!-- 圆形区域向里缩进的距离 -->
8 </declare-styleable>
默认变量:
1 private static String TAG = "CircleProgressButton";
2 private static final int DEFAULT_MAX_VALUE = 100; // 默认进度条最大值
3 private static final int DEFAULT_PAINT_WIDTH = 10; // 默认画笔宽度
4 private static final int DEFAULT_PAINT_COLOR = 0xffffcc00; // 默认画笔颜色
5 private static final boolean DEFAULT_FILL_MODE = true; // 默认填充模式
6 private static final int DEFAULT_INSIDE_VALUE = 0; // 默认缩进距离
7
8 private CircleAttribute mCircleAttribute; // 圆形进度条基本属性
9
10 private int mMaxProgress; // 进度条最大值
11 private int mMainCurProgress; // 主进度条当前值
12
13
14 private CartoomEngine mCartoomEngine; // 动画引擎
15 private boolean isBCartoom = false;//是否正在作画
16 private Drawable mBackgroundPicture; // 背景图
17 private boolean isPause = false; // 是否暂停
18 private int mPlayTime; // 播放时间
19 private OnCompletedListener mCompLsn;
20 private boolean finishFlag = false;
重写onDraw方法:
public void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
super.onDraw(canvas);
if (mBackgroundPicture == null) // 没背景图的话就绘制底色
{
canvas.drawArc(mCircleAttribute.mRoundOval, 0, 360,
mCircleAttribute.mBRoundPaintsFill,
mCircleAttribute.mBottomPaint);
}
float rate = (float) mMainCurProgress / mMaxProgress;
float sweep = 360 * rate;
canvas.drawArc(mCircleAttribute.mRoundOval, mCircleAttribute.mDrawPos,
sweep, mCircleAttribute.mBRoundPaintsFill,
mCircleAttribute.mMainPaints);
postInvalidate();
}
实时画进度条的类
1 class CartoomEngine {
2 public Handler mHandler = null;
3 public boolean mBCartoom; // 是否正在作动画
4 public Timer mTimer = null; // 用于作动画的TIMER
5 public MyTimerTask mTimerTask = null; // 动画任务
6 public int mSaveMax; // 在作动画时会临时改变MAX值,该变量用于保存值以便恢复
7 public int mTimerInterval; // 定时器触发间隔时间(ms)
8 public float mCurFloatProcess; // 作动画时当前进度值
9 private int time;
10 //private long timeMil;
11
12 public CartoomEngine() {
13
14 mBCartoom = false;
15 isBCartoom = mBCartoom;
16 mTimer = new Timer();
17 mSaveMax = 0;
18 mTimerInterval = 50;
19 mCurFloatProcess = 0;
20
21 mHandler = new Handler() {
22
23 @Override
24 public void handleMessage(Message msg) {
25 // TODO Auto-generated method stub
26 switch (msg.what) {
27 case TIMER_ID: {
28 if (mBCartoom == false) {
29 return;
30 }
31
32 mCurFloatProcess += 1;
33 setMainProgress((int) mCurFloatProcess);
34 // Log.d("start", ""+mCurFloatProcess);
35 //long curtimeMil = System.currentTimeMillis();
36
37 //timeMil = curtimeMil;
38
39 if (mCurFloatProcess >= mMaxProgress) {
40 stopCartoom();
41 mCurFloatProcess = 0;
42 if(finishFlag&&!isBCartoom){
43 mCompLsn.OnCompleted(CircleProgressButton.this, !isBCartoom);
44 }
45 }
46 }
47 break;
48 }
49 }
50
51 };
52
53 }
54
55 public synchronized void startCartoom() {
56 setTime(mPlayTime);
57 if (time <= 0 ) {
58 return;
59 }
60 if (mTimer == null) {
61 mTimer = new Timer();
62 }
63
64 if (mTimerTask == null) {
65 mTimerTask = new MyTimerTask();
66 }
67
68 //timeMil = 0;
69
70 mBCartoom = true;
71 isBCartoom = mBCartoom;
72
73 mSaveMax = mMaxProgress;
74 mMaxProgress = (1000 / mTimerInterval) * time;
75
76
77 if (mTimer != null && mTimerTask != null) {
78 mTimer.schedule(mTimerTask, mTimerInterval, mTimerInterval);
79 }
80
81 }
82
83 public synchronized void stopCartoom() {
84
85
86 mBCartoom = false;
87 isBCartoom = mBCartoom;
88 isPause = false;
89 mMaxProgress = mSaveMax;
90 mCurFloatProcess = 0;
91 setMainProgress(0);
92
93 if (mTimerTask != null) {
94 mTimerTask.cancel();
95 mTimerTask = null;
96
97 }
98 }
99
100 public synchronized void pauseCartoom() {
101
102 mBCartoom = false;
103 isBCartoom = mBCartoom;
104 isPause = true;
105 // Log.d("pause1", ""+mCurFloatProcess);
106 setMainProgress((int) mCurFloatProcess);
107
108
109 // Log.d("pause2", ""+mCurFloatProcess);
110 if (mTimerTask != null) {
111 mTimerTask.cancel();
112 mTimerTask = null;
113
114 }
115 }
116
117 public int getTime() {
118 return time;
119 }
120
121 public void setTime(int time) {
122 this.time = time;
123 }
124
125 private final static int TIMER_ID = 0x0010;
126
127 class MyTimerTask extends TimerTask {
128 @Override
129 public void run() {
130 // TODO Auto-generated method stub
131 Message msg = mHandler.obtainMessage(TIMER_ID);
132 msg.sendToTarget();
133 }
134
135 }
136 }