自定义progressdialog——带倒计时的progressbar效果

先上图:

自定义progressdialog——带倒计时的progressbar效果_第1张图片

 

核心就在于progress中的dialog和bar的合用,bar也是自定义的,值得一提的是progressbar是为数不多的继承至View的控件,那么就代表着可拓展性很强~~~开始是考虑直接自定义dialog实现,但是因为不能重写onDraw只能改属性或者onCreate,卡住了,如果有用自定义dialog实现了请给点思路或者给个demo,小子不胜感激~

 

工程目录,很简单:

自定义progressdialog——带倒计时的progressbar效果_第2张图片

注意一下,用了向下兼容的属性动画包

 

自定义progressbar的代码,核心是onDraw和onMeasure

@Override
	protected void onDraw(Canvas canvas) {
		canvas.drawColor(getResources().getColor(R.color.white_navy));//画布背景色
		
		mPaint.setColor(getResources().getColor(R.color.white_light));
		mPaint.setAntiAlias(true);
		mPaint.setStyle(Style.STROKE);//空心
		mPaint.setStrokeWidth(strokeWidth);//线的宽度
		canvas.drawCircle(getWidth()/2, getHeight()/2, mRadius, mPaint);
		
		mPaint.setColor(getResources().getColor(R.color.orange_light));
		mPaint.setStrokeWidth(strokeWidth+4);//覆盖线的宽度
		mPaint.setAntiAlias(true);
		/**
		 * oval :指定圆弧的外轮廓矩形区域。计算方式看看就清楚了,核心是x、y相关的坐标
 		startAngle: 圆弧起始角度,单位为度。
 		sweepAngle: 圆弧扫过的角度,顺时针方向,单位为度,从右中间开始为零度。
 		useCenter: 如果为True时,在绘制圆弧时将圆心包括在内,
		 */
//		Log.e("max", ""+getMax());
//		Log.e("getProgress", ""+getProgress());
		float sweepAngle = getProgress() * 1.0f / getMax() * 360;//根据现在值和最大值的百分比计算出弧线现在的度数
		canvas.drawArc(new RectF(getPaddingLeft(), getPaddingTop(), getPaddingLeft()+strokeWidth+mRadius*2, getPaddingTop()+strokeWidth+mRadius*2), -90,
				sweepAngle, false, mPaint);
		
	}
	@Override
	protected synchronized void onMeasure(int widthMeasureSpec,
			int heightMeasureSpec) {
		//根据半径算出占屏幕的比重,圆环宽,padding相关
		int widthSize = mRadius * 2 + strokeWidth+getPaddingLeft()+getPaddingRight();
		setMeasuredDimension(widthSize, widthSize);
	}	

注释的很详细,没有画双环圆,就用弧线覆盖的方式实现的


自定义progressdialog:

/**
 * 自定义的dialog,展示自定义的progressbar
 * @author sen
 */
public class CustomTimingProgressDialog extends ProgressDialog {

//	private Context context;
	private TextView dialog_tv_test;
	private CustomTimingCircle dialog_tv_cc;
	private Timer timer;
	public CustomTimingProgressDialog(Context context) {
		super(context);
//		this.context = context;
	}

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.custom_timing_progress_dialog);
		dialog_tv_test = (TextView) findViewById(R.id.dialog_tv_test);
		dialog_tv_cc = (CustomTimingCircle) findViewById(R.id.dialog_tv_cc);
		dialog_tv_cc.setMax(100);
		
		timer = new Timer();
		//计时器任务,延迟多少开始数,数的速度
		timer.schedule(timerTask, 0,1000);
		//这里用的是nineold的属性动画向下兼容包
		ValueAnimator animator = ValueAnimator.ofInt(100,0);
		animator.setDuration(5000);
		animator.addUpdateListener(new AnimatorUpdateListener() {
			
			@Override
			public void onAnimationUpdate(ValueAnimator animation) {
				int animatedValue = (Integer) animation.getAnimatedValue();
				dialog_tv_cc.setProgress(animatedValue);
			}
		});
		animator.start();
	}
	
	Handler handler = new Handler() {
		@Override
		public void handleMessage(Message msg) {
//			super.handleMessage(msg);
			if (msg.what > 0) {
				dialog_tv_test.setText(msg.what+ "\n秒");
			} else {
				dialogDismiss();
			}
		}
	};
	
	TimerTask timerTask = new TimerTask() {
		int second = 5;
		@Override
		public void run() {
			Message msg = new Message();
			msg.what = second;
			handler.sendMessage(msg);
			second--;
//			Log.e("second", "" + second);
		}
	};
	/**
	 * 强制取消掉dialog,同样的计时器也同时取消掉
	 *  看具体情况来判断是否打开新的界面
	 */
	public void dialogDismiss() {
		this.dismiss();
		timer.cancel();
	}
 

xml______________________________

 



    
    
    


额,好像注释有点少,不过很简单。onCreate,xml是核心,用timerTask和Handler控制对文本的改变,属性动画控制bar的progress值的改变,实现动画效果。

 

主函数的代码片也放上来吧

@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
	}
	
	public void ok(View v){
		new CustomTimingProgressDialog(this).show();
	}


 


 demo下载

 

相关学习:郭神的属性动画 上中下

              洋神的自定义控件系列

 

 

 

你可能感兴趣的:(Android——实例演示记录)