Android倒計時功能的簡單實現和改進

來源:互聯網
上載者:User

項目中經常會遇到找回密碼的功能,現在找回密碼一般都是用手機接收驗證碼,為了防止多次發送,一般需要設定一個發送間隔,比如60秒。為了讓使用者更加清楚的感受到這個間隔,於是就出現了倒計時功能.如下圖:

點擊之後,擷取驗證碼的那個TextView或者Button變為不可點擊,並且它的的text就要每秒變化一次,59,58,57…到最後一秒之後,text重新變為點擊擷取驗證碼,而且變為可點擊.

看了一些前輩寫的倒計時,都是用Handler和TimerTask來實現,然後我發現了一個更加簡單的,Android內建的類來寫這個功能.

接下來我就以一個簡單的例子來實現這個功能。

1、activity_main.XML,為一個Button即可.

<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”
>

<Button
android:textSize=”25dp”
android:id=”@+id/btn_get”
android:layout_width=”fill_parent”
android:layout_height=”fill_parent”
android:text=”點擊擷取驗證碼” />

</RelativeLayout>

2、MainActivity.java,既為重頭戲,又極為簡單.

package com.example.rr;

import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class MainActivity extends Activity {

private Button mButton;//定義一個Button
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mButton=(Button) findViewById(R.id.btn_get);//←←擷取按鈕ID
//設定監聽↓↓
mButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
mButton.setClickable(false);
mButton.setTextColor(Color.parseColor(“#FF0000″));
MyTimer myTimer=new MyTimer(5000, 1000);//定義MyTimer的對象
myTimer.start();//啟動倒計時
}});

}
private class MyTimer extends CountDownTimer{

//millisInFuture為你設定的此次倒計時的總時間長度,比如60秒就設定為60000
//countDownInterval為你設定的時間間隔,比如一般為1秒,根據需要自訂。
public MyTimer(long millisInFuture, long countDownInterval) {
super(millisInFuture, countDownInterval);
// TODO Auto-generated constructor stub

}@Override
public void onTick(long millisUntilFinished) {
// TODO Auto-generated method stub
mButton.setText(millisUntilFinished/1000+”秒後重新擷取”);
}
//每過你規定的時間間隔做的操作↑↑
//倒計時結束時做的操作↓↓
@Override
public void onFinish() {
// TODO Auto-generated method stub
mButton.setClickable(true);
mButton.setTextColor(Color.parseColor(“#000000”));
mButton.setText(“點擊擷取驗證碼”);
}}}

在各個關鍵點我也做了標註,下面是我給大家錄的gif.

timer

大家可以發現有2個問題:

1、在1秒的時候,會停頓大約兩秒,這樣就給了使用者不太好的體驗,還以為是手機卡了.為什麼會出現這種問題呢?

2、點擊Button時,出現的是數字4而不是數字5。

首先我們得知道這種方法的原理是什麼,大家先看一下CountDownTimer的源碼:

首先大家看一下這句: mStopTimeInFuture = SystemClock.elapsedRealtime() + mMillisInFuture;

再看下下面的這句:  final long millisLeft = mStopTimeInFuture – SystemClock.elapsedRealtime();

(注意:SystemClock.elapsedRealtime()返回的是系統運行到現在的時間,每時每刻都在變化);

如果簡單的進行數學計算的話,那麼一開始mStopTimeInFuture是等於millisLeft的,但是不然,SystemClock.elapsedRealtime()返回的時間,以毫秒為單位,也就是說,從上面運行到下面,也消耗了些許時間,那麼millisLeft就是小於5000的。

回到我們的Activity,我們在內部類的OnTick裡寫了什嗎?

mButton.setText(millisUntilFinished/1000+”秒後重新擷取”);那麼4900多除以1000後,返回的數值為4。

 解決方案:

                   在我們執行個體化MyTimer時,將5000改為6000.

 至於在1秒處停頓的情況,我們看一下最下面的if else 語句:

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);

在 else if 語句處,當millisLeft<mCountdownInterval=1000,時,只進行停頓,而不調用OnTick方法,也就是說,我們運行程式時,millisLeft的數值從4900多~3900~2900~1900~900,900的時候,運行到這裡,就會停頓,而不顯示我們在OnTick寫的代碼.

           解決方案:

       重寫CountDownTimer類。 

      然後, 

     1、在else if 中加OnTick(millisLeft);

2、刪掉這個if  else 語句

    OK,我在重寫類之後,將if else 語句改為下面的時候,依舊可以完成倒計時功能:

 if (millisLeft <= 0) {
onFinish();
} else {
onTick(millisLeft);
sendMessageDelayed(obtainMessage(MSG), 1000);
}

效果gif如下:

是不是寫這個類的大牛想複雜了,還是我這個方法有問題呢?有知道的道友可以聯絡我~萬分感謝!

PS:寫這個文章浪費了快一下午,原因是網速不好,快寫完了,儲存草稿,然後出現意外,導致沒儲存,所以,,,,但是還是希望得到各位的建議和鼓勵,謝謝!

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.