欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android CountDownTimer实现倒计时器

程序员文章站 2023-12-18 09:47:22
使用介绍 开发中经常会遇到一些和倒计时有关的场景,比如发送验证码的按钮,会在点击发送后,显示倒计时间,倒计时结束后才能够刷新按钮,再次允许点击。为了不阻塞软件的运行,...

使用介绍

开发中经常会遇到一些和倒计时有关的场景,比如发送验证码的按钮,会在点击发送后,显示倒计时间,倒计时结束后才能够刷新按钮,再次允许点击。为了不阻塞软件的运行,又要实时刷新界面,我们通常会用到 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);
        }
      }
    }
  };
}

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

上一篇:

下一篇: