记得最开始做Android开发的时候,倒计时功能都是通过Handle的方式实现的。
比如下面这种方式。
-
通过Handle实现
- 首先定义一个handle处理消息。
class TimerHandler extends Handler{ private LoginHelper helper; TimerHandler(LoginHelper helper){ this.helper= new WeakReference<>(helper).get(); } @Override public void handleMessage(Message msg) { super.handleMessage(msg); switch (msg.what){ case 2: helper.checkCodeLogic(); break; } } }
- 然后就是每一秒发送一条消息。
private void checkCodeLogic(){ if(timeNow<=0){ tvCheck.setEnabled(true); tvCheck.setText(activity.getResources().getString(R.string.login_post_check)); tvCheck.setTextColor(activity.gColor(R.color.theme_fore_bg)); tvCheck.setTag(null); }else{ tvCheck.setEnabled(false); tvCheck.setText(timeNow+"s后重新获取"); handler.sendEmptyMessageDelayed(2,1000); tvCheck.setTextColor(activity.gColor(R.color.theme_focus)); tvCheck.setTag(1); timeNow--; } }
- 设置倒计时时间,触发倒计时
private void startTimer(){ timeNow=60; checkCodeLogic(); }
这种方式实现还是挺麻烦的,但是在哪个资源匮乏的时候,很多东西还是需要自己撸一个的。
通过CountDownTimer,这也是谷歌推荐的方式,其实大家去看看源码就会发现,这种方式也是基于handle实现,实现起来也是特别的简洁。
//设置总时长60s, 没1s触发一次onTick
CountDownTimer timer = new CountDownTimer(60000,1000) {
@Override
public void onTick(long l) {
// l 返回的是剩余毫秒数
verificationCodeTv.setText((l / 1000) + "倒计时");
}
@Override
public void onFinish() {
//倒计时结束后调用
verificationCodeTv.setText("獲取驗證碼");
verificationCodeTv.setEnabled(true);
}
};
- 通过Rxjava实现。Rxjava是基于观察者模式的,用来实现倒计时的功能也是十分简单优雅的。
//设置0延迟,每隔一秒发送一条数据
Observable.interval(0, 1, TimeUnit.SECONDS)
.take(60) //60s倒计时
.map(new Function<Long, Long>() {
@Override
public Long apply(@NonNull Long aLong) throws Exception {
return 60 - aLong;
}
}) //处理下返回的数据
.doOnSubscribe(new Consumer<Disposable>() {
@Override
public void accept(@NonNull Disposable disposable) throws Exception {
//在发送数据的时候设置控件的样式
mTv.setEnabled(false);
}
})
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<Long>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(Long aLong) {
//每隔1s执行的动作
mTv.setText(aLong+"s后重新获取");
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
//60s倒计时完成后,修改控件样式
mTv.setEnabled(false);
}
});