服务器之家:专注于服务器技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - Android - 使用CountDownTimer类轻松实现倒计时功能

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

2021-03-04 13:19Android开发网 Android

Android中有个countDownTimer类,从名字上就可以看出来,它的功能是记录下载时间,将后台线程的创建和Handler队列封装成为了一个方便的调用。

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

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

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

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

直接上代码:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
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!
//┃   ┗━━━┓
//┃       ┣┓
//┃       ┏┛
//┗┓┓┏━┳┓┏┛
// ┃┫┫ ┃┫┫
// ┗┻┛ ┗┻┛

布局:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<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源码:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
/*
 * 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);
        }
      }
    }
  };
}

 

延伸 · 阅读

精彩推荐