当前位置: 移动技术网 > IT编程>移动开发>Android > Android CountDownTimer实现倒计时器

Android CountDownTimer实现倒计时器

2019年07月24日  | 移动技术网IT编程  | 我要评论

申思近况,李成福,斯拉兹

使用介绍

开发中经常会遇到一些和倒计时有关的场景,比如发送验证码的按钮,会在点击发送后,显示倒计时间,倒计时结束后才能够刷新按钮,再次允许点击。为了不阻塞软件的运行,又要实时刷新界面,我们通常会用到 handler 或者 asynctask 等技术,自己写逻辑实现。其实 android 中已经封装好了一套 countdowntimer 来实现这个功能需求。

countdowntimer(long millisinfuture, long countdowninterval)

countdowntimer的两个参数分别表示倒计时的总时间 millisinfuture 和间隔时间 countdowninterval

具体的调用如下:

textview vertifybtn;
countdowntimer timer = new countdowntimer(60000, 1000) {

  @override
  public void ontick(long millisuntilfinished) {
    vertifybtn.settext((millisuntilfinished / 1000) + " second");
  }
  
  @override
  public void onfinish() {
    vertifybtn.setenabled(true);
    vertifybtn.settext("send");
  }
};
timer.start();

上面的调用举例表示总计 60 秒,每 1 秒都会执行一次 ontick 方法,其参数 millisuntilfinished 表示倒计时剩余时间毫秒数,最后倒计时结束执行 onfinish 方法。

实现原理

下面是 countdowntimer 的源码,代码非常少,很好理解。从源代码中可以看出,其实 countdowntimer 也是利用 handler 的消息处理机制来实现效果的。初始化设定好起始和终止时间后,每隔一定的间隔时间通过 handler 给主线程发送消息,然后再在消息处理中回调方法。好好利用官方封装好的工具类,可以避免我们重复的造轮子,当然了解轮子的原理就更好了!

package android.os;

public abstract class countdowntimer {
  private final long mmillisinfuture;
  private final long mcountdowninterval;
  private long mstoptimeinfuture;
  private boolean mcancelled = false;

  public countdowntimer(long millisinfuture, long countdowninterval) {
    mmillisinfuture = millisinfuture;
    mcountdowninterval = countdowninterval;
  }

  public synchronized final void cancel() {
    mcancelled = true;
    mhandler.removemessages(msg);
  }

  public synchronized final countdowntimer start() {
    mcancelled = false;
    if (mmillisinfuture <= 0) {
      onfinish();
      return this;
    }
    mstoptimeinfuture = systemclock.elapsedrealtime() + mmillisinfuture;
    mhandler.sendmessage(mhandler.obtainmessage(msg));
    return this;
  }

  public abstract void ontick(long millisuntilfinished);

  public abstract void onfinish();

  private static final int msg = 1;
  
  private handler mhandler = new handler() {

    @override
    public void handlemessage(message msg) {

      synchronized (countdowntimer.this) {
        if (mcancelled) {
          return;
        }

        final long millisleft = mstoptimeinfuture - systemclock.elapsedrealtime();

        if (millisleft <= 0) {
          onfinish();
        } else if (millisleft < mcountdowninterval) {
          // no tick, just delay until done
          sendmessagedelayed(obtainmessage(msg), millisleft);
        } else {
          long lasttickstart = systemclock.elapsedrealtime();
          ontick(millisleft);

          // take into account user's ontick taking time to execute
          long delay = lasttickstart + mcountdowninterval - systemclock.elapsedrealtime();

          // special case: user's ontick took more than interval to
          // complete, skip to next interval
          while (delay < 0) delay += mcountdowninterval;

          sendmessagedelayed(obtainmessage(msg), delay);
        }
      }
    }
  };
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持移动技术网。

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网