您的位置:首页 > 其它

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

2015-06-10 10:15 363 查看
先上图:





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



工程目录,很简单:



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



自定义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______________________________



<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <com.ob.testdemo.CustomTimingCircle
        android:id="@+id/dialog_tv_cc"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:layout_centerInParent="true"
       android:padding="10dip"
       />
    
    <TextView 
        android:id="@+id/dialog_tv_test"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center_vertical|center_horizontal"
        android:layout_centerInParent="true"
        android:text="5\n秒"
        android:textColor="@color/orange_light"
        />
</RelativeLayout>


额,好像注释有点少,不过很简单。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();
	}




<Button 
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:onClick="ok"
        android:text="测试"
        />


demo下载



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

洋神的自定义控件系列
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: