Android开发之设置60s倒计时

同样是最近做项目碰到的一点小知识,拿出来和大家分享一下。要实现的功能是点击发送按钮后手机会接收到验证码,但是有的时候由于短信网关故障等原因可能不能及时收到短息,所以设置一种倒计时机制,当倒计时时间结束后如果还没有收到验证码短信则可以选择重新发送验证码。

首先说一下我们今天用的到CountDownTimer这个抽象类,实现了倒计时的功能。将后台线程的创建和Handler队列封装成一个方便的类调用。这个类比较简单,只有四个方法:onTick,onFinsh、cancel和start。其中前面两个是抽象方法,所以要重写一下。

下面是一个小例子:

主界面非常简单,只定义了一个按钮,布局代码如下:

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

    <Button
        android:id="@+id/get_code_btn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="获取验证码" />

</RelativeLayout>
然后是主界面MainActivity.java代码:

import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Intent;

/**
 * 主界面
 * 
 * @author zyb
 * 
 */
public class MainActivity extends Activity {

	private Button mGetCodeBtn;// 倒计时按钮
	private Intent mIntent;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		initView();
	}

	/**
	 * 初始化视图
	 */
	private void initView() {
		mGetCodeBtn = (Button) findViewById(R.id.get_code_btn);
		RegisterCodeTimerService.setHandler(mCodeHandler);
		mIntent = new Intent(MainActivity.this, RegisterCodeTimerService.class);
		mGetCodeBtn.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				mGetCodeBtn.setEnabled(false);
				startService(mIntent);
			}
		});
	}

	/**
	 * 倒计时Handler
	 */
	@SuppressLint("HandlerLeak")
	Handler mCodeHandler = new Handler() {
		public void handleMessage(Message msg) {
			if (msg.what == RegisterCodeTimer.IN_RUNNING) {// 正在倒计时
				mGetCodeBtn.setText(msg.obj.toString());
			} else if (msg.what == RegisterCodeTimer.END_RUNNING) {// 完成倒计时
				mGetCodeBtn.setEnabled(true);
				mGetCodeBtn.setText(msg.obj.toString());
			}
		};
	};

	@Override
	protected void onDestroy() {
		// TODO Auto-generated method stub
		super.onDestroy();
		stopService(mIntent);
	}

}
从上面的代码可以看出,主要是使用了一个RegisterCodeTimerService来完成倒计时,这样就算页面跳转了也不会停止倒计时, RegisterCodeTimerService.java代码如下:

import android.app.Service;
import android.content.Intent;
import android.os.Handler;
import android.os.IBinder;

/**
 * 注册验证码计时服务
 * 
 * @author zyb
 * 
 */
public class RegisterCodeTimerService extends Service {

	private static Handler mHandler;
	private static RegisterCodeTimer mCodeTimer;

	@Override
	public IBinder onBind(Intent intent) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public void onCreate() {
		// TODO Auto-generated method stub
		super.onCreate();
	}

	@SuppressWarnings("deprecation")
	@Override
	public void onStart(Intent intent, int startId) {
		// TODO Auto-generated method stub
		super.onStart(intent, startId);
		mCodeTimer = new RegisterCodeTimer(60000, 1000, mHandler);
		mCodeTimer.start();
	}

	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		// TODO Auto-generated method stub
		return super.onStartCommand(intent, flags, startId);
	}

	@Override
	public void onDestroy() {
		// TODO Auto-generated method stub
		super.onDestroy();
	}

	/**
	 * 设置Handler
	 */
	public static void setHandler(Handler handler) {
		mHandler = handler;
	}

}

最后当然是最关键的,使用我们上面提到过的 CountDownTimer这个抽象类,RegisterCodeTimer.java代码如下:

import android.os.Handler;

/**
 * 注册验证码计时器
 * 
 * @author zyb
 * 
 */
public class RegisterCodeTimer extends CountDownTimer {
	private static Handler mHandler;
	public static final int IN_RUNNING = 1001;
	public static int END_RUNNING = 1002;

	/**
	 * @param millisInFuture
	 *            // 倒计时的时长
	 * @param countDownInterval
	 *            // 间隔时间
	 * @param handler
	 *            // 通知进度的Handler
	 */
	public RegisterCodeTimer(long millisInFuture, long countDownInterval,
			Handler handler) {
		super(millisInFuture, countDownInterval);
		mHandler = handler;
	}

	// 结束
	@Override
	public void onFinish() {
		// TODO Auto-generated method stub
		if (mHandler != null)
			mHandler.obtainMessage(END_RUNNING, "重发").sendToTarget();
	}

	@Override
	public void onTick(long millisUntilFinished) {
		// TODO Auto-generated method stub
		if (mHandler != null)
			mHandler.obtainMessage(IN_RUNNING,
					(millisUntilFinished / 1000) + "s 后重发").sendToTarget();
	}

}

onFinish()中的代码是计时器结束的时候要做的事情

onTick(Long millisUntilFinished)中的代码是你倒计时开始时要做的事情,参数millisUntilFinished是完成的时间。

到这里就完全实现了倒计时功能,由于上面的代码非常的完整,我就不分享源码了,如果有需要的可以留下你的邮箱,我再发给你。




版权声明:本文为u011895534原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。