項目開發中,碰到了需要在apk啓動進入程序時顯示一個幾秒中的廣告圖及註冊或修改密碼時需要獲取驗證碼的效果,其實android系統已經封裝了一個倒計時的類:CountDownTimer,可以很輕鬆的實現一個倒計時的效果。
效果如下:
代碼實現如下:
/**
* 倒計時幫助類
*/
public class CountDownUtils {
// 倒計時timer
private CountDownTimer countDownTimer;
// 計時結束的回調接口
private OnFinishListener listener;
private Button button;
/**
* @param button 需要顯示倒計時的Button
* @param defaultString 默認顯示的字符串
* @param max 需要進行倒計時的最大值,單位是秒
* @param interval 倒計時的間隔,單位是秒
*/
public CountDownUtils(WeakReference<Button> weakReference,
final String defaultString, int max, int interval) {
if(weakReference==null){
return;
}
Button btn= weakReference.get();
if(btn==null){
return;
}
this.button = btn;
// 由於CountDownTimer並不是準確計時,在onTick方法調用的時候,time會有1-10ms左右的誤差,這會導致最後一秒不會調用onTick()
// 因此,設置間隔的時候,默認減去了10ms,從而減去誤差。
// 經過以上的微調,最後一秒的顯示時間會由於10ms延遲的積累,導致顯示時間比1s長max*10ms的時間,其他時間的顯示正常,總時間正常
countDownTimer = new CountDownTimer(max * 1000, interval * 1000 - 10) {
@Override
public void onTick(long time) {
// 第一次調用會有1-10ms的誤差,因此需要+15ms,防止第一個數不顯示,第二個數顯示2s
button.setText(defaultString + "(" + ((time + 15) / 1000)
+ "s)");
Log.d("CountDownUtils", "time = " + (time) + " text = "
+ ((time + 15) / 1000));
}
@Override
public void onFinish() {
button.setEnabled(true);
button.setText(defaultString);
if (listener != null) {
listener.finish();
}
}
};
}
/**
* 開始倒計時
*/
public void start(boolean isUser) {
if (isUser) {
button.setEnabled(true);
} else {
button.setEnabled(false);
}
countDownTimer.start();
}
/**
* 設置倒計時結束的監聽器
*
* @param listener
*/
public void setOnFinishListener(OnFinishListener listener) {
this.listener = listener;
}
/**
* 計時結束的回調接口
*
* @author zhaokaiqiang
*/
public interface OnFinishListener {
void finish();
}
}
將CountDownTimer封裝成一個工具類,在使用的時候調用傳入相應的參數就可以了;
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.countdowntime.MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="50dp"
android:orientation="horizontal"
android:id="@+id/tel_layout">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="手機號:"
android:textColor="#000000"
android:textSize="13sp"
android:layout_gravity="center_vertical"
android:layout_marginLeft="15dp"/>
<EditText
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="15dp"
android:hint="請輸入手機號碼"
android:textSize="13sp"
android:textColor="#000000"
android:inputType="number"/>
</LinearLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_below="@+id/tel_layout">
<TextView
android:id="@+id/tv_code"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="驗證碼:"
android:textColor="#000000"
android:textSize="13sp"
android:layout_centerVertical="true"
android:layout_marginLeft="15dp"/>
<EditText
android:layout_width="150dp"
android:layout_height="match_parent"
android:layout_marginLeft="15dp"
android:hint="請輸入驗證碼"
android:textSize="13sp"
android:textColor="#000000"
android:inputType="number"
android:layout_toRightOf="@+id/tv_code"/>
<Button
android:id="@+id/btn_code"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="獲取驗證碼"
android:textSize="11sp"
android:textColor="#000000"
android:layout_alignParentRight="true"
android:layout_marginRight="15dp"
android:layout_centerVertical="true"
android:padding="8dp"
android:background="@drawable/code_button"
android:minHeight="0dp"
android:minWidth="0dp"/>
</RelativeLayout>
<ImageView
android:id="@+id/iv_ID"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@color/colorPrimary"
android:visibility="visible"/>
<Button
android:id="@+id/btn_ID"
android:layout_width="55dp"
android:layout_height="55dp"
android:background="@drawable/time_button"
android:textColor="#000000"
android:textSize="11sp"
android:text="跳過5秒"
android:layout_alignParentRight="true"
android:layout_marginTop="5dp"
android:layout_marginRight="5dp"
android:visibility="visible"/>
</RelativeLayout>
上面這個是佈局文件的代碼,最終獲取相應的控件,調用CountDownUtils工具類中相應的方法;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private ImageView ivTD;
private Button btnID;
private Button btnCode;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ivTD= (ImageView) findViewById(R.id.iv_ID);
btnID= (Button) findViewById(R.id.btn_ID);
btnCode= (Button) findViewById(R.id.btn_code);
showID();
btnID.setOnClickListener(this);
btnCode.setOnClickListener(this);
}
/**
* 顯示活動廣告圖
*/
private void showID(){
CountDownUtils countDown=new CountDownUtils(new WeakReference<Button>(btnID),"跳過", 5, 1);
//監聽倒計時
countDown.setOnFinishListener(new CountDownUtils.OnFinishListener() {
@Override
public void finish() {
//顯示完畢回調
//隱藏掉活動廣告 和按鈕
ivTD.setVisibility(View.GONE);
btnID.setVisibility(View.GONE);
}
});
//開啓活動倒計時
countDown.start(true);
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.btn_ID:
jumpOver();
break;
case R.id.btn_code:
getCode();
break;
}
}
/**
* 點擊了跳過
*/
private void jumpOver() {
//跳過點擊
//隱藏掉活動廣告 和按鈕
ivTD.setVisibility(View.GONE);
btnID.setVisibility(View.GONE);
Toast.makeText(this,"點擊了跳過",Toast.LENGTH_LONG).show();
}
/**
* 獲取驗證碼
*/
private void getCode(){
CountDownUtils codeDown=new CountDownUtils(btnCode,"發送驗證碼", 60, 1);
//監聽倒計時
codeDown.setOnFinishListener(new CountDownUtils.OnFinishListener() {
@Override
public void finish() {
}
});
//開啓活動倒計時
codeDown.start(false);
Toast.makeText(this,"驗證碼已發送",Toast.LENGTH_LONG).show();
}
}
這樣子效果就實現了,沒錯,就這麼簡單。