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

使用CountDownTimer类轻松实现倒计时功能

程序员文章站 2023-02-02 12:09:29
countdowntimer由系统提供 查资料的时候 发现了countdowntimer这个类之后 果断抛弃了以前的倒计时做法 功能: 30秒倒计时 每次间隔1秒...

countdowntimer由系统提供
查资料的时候 发现了countdowntimer这个类之后 果断抛弃了以前的倒计时做法

功能:
30秒倒计时 每次间隔1秒

参数:
mc.start();方法开始

mc.cancel();方法结束
new mycountdowntimer(30000, 1000); 第一个参数表示 总的时间为30000毫秒,间隔1000毫秒

直接上代码:

package com.example.daojishi; 
 
import android.app.activity; 
import android.os.bundle; 
import android.os.countdowntimer; 
import android.util.log; 
import android.view.view; 
import android.widget.textview; 
import android.widget.toast; 
 
/** 
 * 
 * @author baozi 
 * 
 * 倒计时的类 countdowntimer 
 * 
 */ 
public class mainactivity extends activity { 
 
  private mycountdowntimer mc; 
  private textview tv; 
 
  @override 
  protected void oncreate(bundle savedinstancestate) { 
    super.oncreate(savedinstancestate); 
    setcontentview(r.layout.activity_main); 
    tv = (textview) findviewbyid(r.id.show); 
    mc = new mycountdowntimer(30000, 1000); 
    mc.start(); 
  } 
 
  public void oncancel(view view) { 
    toast.maketext(mainactivity.this, "取消", toast.length_long).show();// toast有显示时间延迟 
    mc.cancel(); 
  } 
 
  public void restart(view view) { 
    toast.maketext(mainactivity.this, "重新开始", toast.length_long).show();// toast有显示时间延迟 
    mc.start(); 
  } 
 
  /** 
   * 继承 countdowntimer 防范 
   * 
   * 重写 父类的方法 ontick() 、 onfinish() 
   */ 
 
  class mycountdowntimer extends countdowntimer { 
    /** 
     * 
     * @param millisinfuture 
     *      表示以毫秒为单位 倒计时的总数 
     * 
     *      例如 millisinfuture=1000 表示1秒 
     * 
     * @param countdowninterval 
     *      表示 间隔 多少微秒 调用一次 ontick 方法 
     * 
     *      例如: countdowninterval =1000 ; 表示每1000毫秒调用一次ontick() 
     * 
     */ 
    public mycountdowntimer(long millisinfuture, long countdowninterval) { 
      super(millisinfuture, countdowninterval); 
    } 
 
    @override 
    public void onfinish() { 
      tv.settext("done"); 
    } 
 
    @override 
    public void ontick(long millisuntilfinished) { 
      log.i("mainactivity", millisuntilfinished + ""); 
      tv.settext("倒计时(" + millisuntilfinished / 1000 + ")..."); 
    } 
  } 
} 
//┏┓   ┏┓ 
//┏┛┻━━━┛┻┓ 
//┃       ┃   
//┃   ━   ┃ 
//┃ ┳┛ ┗┳ ┃ 
//┃       ┃ 
//┃   ┻   ┃ 
//┃       ┃ 
//┗━┓   ┏━┛ 
//┃   ┃  神兽保佑         
//┃   ┃  代码无bug! 
//┃   ┗━━━┓ 
//┃       ┣┓ 
//┃       ┏┛ 
//┗┓┓┏━┳┓┏┛ 
// ┃┫┫ ┃┫┫ 
// ┗┻┛ ┗┻┛ 

布局:

<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" 
  android:paddingbottom="@dimen/activity_vertical_margin" 
  android:paddingleft="@dimen/activity_horizontal_margin" 
  android:paddingright="@dimen/activity_horizontal_margin" 
  android:paddingtop="@dimen/activity_vertical_margin" 
  tools:context=".mainactivity" > 
 
  <textview 
    android:id="@+id/show" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:text="@string/hello_world" /> 
 
  <button 
    android:id="@+id/button1" 
    android:onclick="oncancel" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:layout_alignleft="@+id/show" 
    android:layout_below="@+id/show" 
    android:layout_marginleft="50dp" 
    android:layout_margintop="106dp" 
    android:text="cancel" /> 
 
  <button 
    android:id="@+id/button2" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:layout_alignleft="@+id/button1" 
    android:layout_below="@+id/button1" 
    android:layout_margintop="63dp" 
    android:onclick="restart" 
    android:text="restart" /> 
 
</relativelayout> 

附:
countdowntimer源码:

/* 
 * copyright (c) 2008 the android open source project 
 * 
 * licensed under the apache license, version 2.0 (the "license"); 
 * you may not use this file except in compliance with the license. 
 * you may obtain a copy of the license at 
 * 
 *   http://www.apache.org/licenses/license-2.0 
 * 
 * unless required by applicable law or agreed to in writing, software 
 * distributed under the license is distributed on an "as is" basis, 
 * without warranties or conditions of any kind, either express or implied. 
 * see the license for the specific language governing permissions and 
 * limitations under the license. 
 */ 
 
package android.os; 
 
import android.util.log; 
 
/** 
 * schedule a countdown until a time in the future, with 
 * regular notifications on intervals along the way. 
 * 
 * example of showing a 30 second countdown in a text field: 
 * 
 * 
 * new countdowntimer(30000, 1000) { 
 * 
 *   public void ontick(long millisuntilfinished) { 
 *     mtextfield.settext("seconds remaining: " + millisuntilfinished / 1000); 
 *   } 
 * 
 *   public void onfinish() { 
 *     mtextfield.settext("done!"); 
 *   } 
 * }.start(); 
 * 
 * 
 * the calls to {@link #ontick(long)} are synchronized to this object so that 
 * one call to {@link #ontick(long)} won't ever occur before the previous 
 * callback is complete. this is only relevant when the implementation of 
 * {@link #ontick(long)} takes an amount of time to execute that is significant 
 * compared to the countdown interval. 
 */ 
public abstract class countdowntimer { 
 
  /** 
   * millis since epoch when alarm should stop. 
   */ 
  private final long mmillisinfuture; 
 
  /** 
   * the interval in millis that the user receives callbacks 
   */ 
  private final long mcountdowninterval; 
 
  private long mstoptimeinfuture; 
 
  /** 
   * @param millisinfuture the number of millis in the future from the call 
   *  to {@link #start()} until the countdown is done and {@link #onfinish()} 
   *  is called. 
   * @param countdowninterval the interval along the way to receive 
   *  {@link #ontick(long)} callbacks. 
   */ 
  public countdowntimer(long millisinfuture, long countdowninterval) { 
    mmillisinfuture = millisinfuture; 
    mcountdowninterval = countdowninterval; 
  } 
 
  /** 
   * cancel the countdown. 
   */ 
  public final void cancel() { 
    mhandler.removemessages(msg); 
  } 
 
  /** 
   * start the countdown. 
   */ 
  public synchronized final countdowntimer start() { 
    if (mmillisinfuture <= 0) { 
      onfinish(); 
      return this; 
    } 
    mstoptimeinfuture = systemclock.elapsedrealtime() + mmillisinfuture; 
    mhandler.sendmessage(mhandler.obtainmessage(msg)); 
    return this; 
  } 
 
 
  /** 
   * callback fired on regular interval. 
   * @param millisuntilfinished the amount of time until finished. 
   */ 
  public abstract void ontick(long millisuntilfinished); 
 
  /** 
   * callback fired when the time is up. 
   */ 
  public abstract void onfinish(); 
 
 
  private static final int msg = 1; 
 
 
  // handles counting down 
  private handler mhandler = new handler() { 
 
    @override 
    public void handlemessage(message msg) { 
 
      synchronized (countdowntimer.this) { 
        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); 
        } 
      } 
    } 
  }; 
}