关于实现类似于圆形ProgressBar的播放进度条

chenjinlong 2012-04-24

我们要实现一个类似于小米分享中的圆形播放进度条,android自带的圆形ProgressBar是默认自动旋转的,所以无法实现,于是我们想到了使用自定义一个View,来实现这种效果。

首先来看看自己定义的View

packagecn.easymobi.application.bell.common;

importandroid.content.Context;

importandroid.graphics.Canvas;

importandroid.graphics.Color;

importandroid.graphics.Paint;

importandroid.graphics.RectF;

importandroid.util.AttributeSet;

importandroid.view.View;

publicclassProgressViewextendsView{

privatefloatfArcNum;

privatefloatfMax;

privatefloatdensity;

publicfloatgetDensity(){

returndensity;

}

publicvoidsetDensity(floatdensity){

this.density=density;

}

publicProgressView(Contextcontext){

super(context);

}

publicProgressView(Contextcontext,AttributeSetattrs){

super(context,attrs);

}

protectedvoidonDraw(Canvascanvas){

//TODOAuto-generatedmethodstub

super.onDraw(canvas);

Paintpaint=newPaint();

if(fArcNum>0)

{

paint.setColor(Color.GRAY);

paint.setFlags(Paint.ANTI_ALIAS_FLAG);

canvas.drawCircle(40*density/2,40*density/2,40*density/2,paint);}

paint.setColor(Color.YELLOW);

paint.setFlags(Paint.ANTI_ALIAS_FLAG);

//paint.setStrokeWidth(2);

RectFrect=newRectF(0,0,40*density,40*density);

canvas.drawArc(rect,-90,fArcNum,true,paint);

paint.setColor(Color.BLACK);

paint.setFlags(Paint.ANTI_ALIAS_FLAG);

canvas.drawCircle(40*density/2,40*density/2,40*density/2-5,paint);

}

publicvoidsetProgress(floatnum)

{

fArcNum = (num/fMax) * 360;

this.postInvalidate();

}

publicfloatgetfArcNum(){

returnfArcNum;

}

publicvoidsetfArcNum(floatfArcNum){

this.fArcNum=fArcNum;

}

publicfloatgetfMax(){

returnfMax;

}

publicvoidsetfMax(floatfMax){

this.fMax=fMax;

}

}

使用:

private ProgressView progress;
	float num=0;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		setContentView(R.layout.clean);
		progress=(ProgressView)findViewById(R.id.progress_main_clean);
		progress.setDensity(1);
		progress.setfMax(100);
		Timer timer=new Timer();
		MyTask task=new MyTask();
		timer.schedule(task,0, 500);
	}
	
	class MyTask extends TimerTask{

		@Override
		public void run() {
			// TODO Auto-generated method stub
			
			progress.setProgress(num);
			System.out.println("number"+num);
			num++;
		}
		
	}

 

我们通过重写View的onDraw方法,根据fArcNum好fMax来判断当前播放到的位置,然后不停的刷新改View就实现了这个效果。至于画弧,是采用了drawArc方法,然后通过在其内部画圆遮盖多余部分实现。

下面是MediaPlayer与该View的同步处理,核心代码如下

//*******************************************************************

//Func:playAudio

//

//by:Sun

//2011.9.1

//*******************************************************************

publicvoidplayAudio(finalStringpath,finalProgressBarpb){

Threadthread=newThread(newRunnable(){

publicvoidrun(){

try{

if(mpMediaPlayer!=null){

mpMediaPlayer.stop();

mpMediaPlayer.release();

mpMediaPlayer=null;

}

mpMediaPlayer=newMediaPlayer();

mpMediaPlayer.setDataSource(path);

mpMediaPlayer.prepare();

mpMediaPlayer

.setOnPreparedListener(newOnPreparedListener(){

publicvoidonPrepared(MediaPlayermp){

pb.setVisibility(ProgressBar.GONE);

frontPv.setfMax(mpMediaPlayer.getDuration());

frontPv.setProgress(0);

mpMediaPlayer.start();

refrash=newThread(newRunnable(){

publicvoidrun(){

try{

while(frontPv.getfArcNum()<=360

&&mpMediaPlayer

.isPlaying()){

if(bIsOver)

break;

frontPv.setProgress(mpMediaPlayer

.getCurrentPosition());

Thread.sleep(1000);

mHandle.sendEmptyMessage(MSG_REFRESH_UI);

}

mHandle.sendEmptyMessage(MSG_PLAY_OVER);

}catch(Exceptione){

e.printStackTrace();

}

}

});

refrash.start();

}

});

}catch(Exceptione){

e.printStackTrace();

}

}

});

thread.start();

}

其中frontPv是我们自己定义的view,最后发送handler是调用invalidate方法刷新该view,mpMediaPlayers是我们定义的MediaPlayer对象。我们通过在进程中每隔一秒更新frontPv当中的fArcNum并且刷新实现转动的动画效果。

原文章出处 http://labs.ywlx.net/?p=1296

相关推荐