倒计时计时器很常用的一个场景是在发送验证码时,往往需要设计倒计时来给用户再次发送验证码,在某一段时间间隔之中,用户不允许对按钮进行再次点击或其他操作。
具体实现如下:
1-自定义一个接口,用来在接受对应方法中传来的相关控件
/**
* 返回定时器相关控件的接口
*/
public interface ITimerUtilListener {
public void getTimer(Timer timer,Handler handler,TimerTask task);
}
2-创建TimerUtil类,执行计时器的具体方法
public class TimerUtil {
private Timer timer;
private Handler handler;
private TimerTask task;
private TextView tv;
private int i;
public TimerUtil(final TextView tv) {
this.tv = tv;
handler = new Handler() {
public void handleMessage(Message msg) {
if (msg.what == 2) {
if(i>=0){
tv.setText("等待"+Integer.toString(--i)+"秒");
if(i == 0){
timer.cancel();
timer = null;
task = null;
tv.setEnabled(true);
tv.setText("重新发送验证码");
}
}else{
return;
}
} else {
//这里相当于接受msg.what == 1时的处理
if(i>=0){
tv.setText("等"+Integer.toString(--i)+"分");
if(i == 0){
timer.cancel();
timer = null;
task = null;
tv.setEnabled(true);
tv.setText("重新发送验证码2");
}
}
}
super.handleMessage(msg);
};
};
}
/**
* 设置验证码计时器
*/
public void setMessageCodeTimeTask(final Context context,
ITimerUtilListener listen) {
tv.setEnabled(false);
if(timer == null){
timer = new Timer();
}
i = 10;
if(task == null){
task = new TimerTask() {
@Override
public void run() {
// 需要做的事:发送消息
Message message = new Message();
message.what = 2;
handler.sendMessage(message);
}
};
}
if(timer != null && task != null){
timer.schedule(task, 1000, 1000); // 1s后执行task,经过1s再次执行
}
listen.getTimer(timer,handler,task);
}
public void setMessageCodeTimeTask2(final Context context,
ITimerUtilListener listen) {
tv.setEnabled(false);
if(timer == null){
timer = new Timer();
}
i = 10;
if(task == null){
task = new TimerTask() {
@Override
public void run() {
// 需要做的事:发送消息
Message message = new Message();
message.what = 1;
handler.sendMessage(message);
}
};
}
if(timer != null && task != null){
timer.schedule(task, 1000, 1000); // 1s后执行task,经过1s再次执行
}
listen.getTimer(timer,handler,task);
}
}
3-MainActivity 中创建相应的TextView或继承自TextView的控件(如Button),在控件的点击事件中执行TimerUtil类中的方法,并将ITimerUtilListener接口中的控件传回,赋给MainActivity中的控件。
PS:TimerUtil 类中参数可以自定义传入其他控件,而不仅仅局限于传TextView。因此处的TimerUtil 类传入的是TextView,故必须传入TextView相关的控件。
public class MainActivity extends Activity {
TextView tv_timerTest;
Button btn_click;
Timer timer;
Handler handler;
TimerTask task;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv_timerTest = (TextView) findViewById(R.id.tv_timerTest);
btn_click = (Button) findViewById(R.id.btn_click);
}
@Override
protected void onResume() {
tv_timerTest.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
//实现点击倒计时
TimerUtil util = new TimerUtil(tv_timerTest);
util.setMessageCodeTimeTask(
MainActivity.this,new ITimerUtilListener() {
@Override
public void getTimer(Timer timer,Handler handler,TimerTask task) {
MainActivity.this.timer = timer;
MainActivity.this.handler = handler;
MainActivity.this.task = task;
}
});
}
});
btn_click.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
//实现点击倒计时
TimerUtil util = new TimerUtil(btn_click);
util.setMessageCodeTimeTask2(
MainActivity.this,new ITimerUtilListener() {
@Override
public void getTimer(Timer timer,Handler handler,TimerTask task) {
MainActivity.this.timer = timer;
MainActivity.this.handler = handler;
MainActivity.this.task = task;
}
});
}
});
super.onResume();
}
}