Android-自定义环形进度条按钮控件
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 }