今天为大家介绍俩种方式,都可以实现倒计时功能。这俩种方式分别是:
- Handler+Thread
- CountDownTimer
想必大家对于第一种实现方式肯定不会陌生了,简直So easy~那再次回顾下第一种写法~
1.通过使用Handler+Thread实现倒计时
首先编写布局文件
布局文件很简单,就是一个TextView,默认显示Handler获取验证码,点击TextView,进行倒计时操作,完成后恢复默认显示。
<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" >
<TextView
android:id="@+id/tv_show_h"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="193dp"
android:text="Handler获取验证码" />
</RelativeLayout>
放大招,编写Activity,实现效果~
public class MainActivity extends Activity {
private TextView tvShowH;
private Handler handler = new Handler() {
public void handleMessage(Message msg) {
tvShowH.setText(msg.what - 1 + "s");
if (msg.what == 0) {
// 倒计时结束让按钮可用
tvShowH.setEnabled(true);
tvShowH.setText("Handler获取验证码");
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tvShowH = (TextView) findViewById(R.id.tv_show_h);
tvShowH.setOnClickListener(listenerH);
}
private OnClickListener listenerH = new View.OnClickListener() {
@Override
public void onClick(View v) {
tvShowH.setEnabled(false);
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 10; i >= 0; i--) {
handler.sendEmptyMessage(i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
}
};
}
new CountdownTimer(30000, 1000) {
public void onTick(long millisUntilFinished) {
mTextField.setText("seconds remaining: " + millisUntilFinished / 1000);
}
public void onFinish() {
mTextField.setText("done!");
}
}.start();
那么这俩个方法分别都是什么作用呢?
3.1 onTick(long millisUntilFinished)
参数millisUntilFinished是倒计时的剩余时间。在倒计时结束后会调用onFinish。
3.2 onFinish()
倒计时结束后需要执行的操作可以写在这里。
<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" >
<TextView
android:id="@+id/tv_show_c"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/tv_show_h"
android:layout_centerHorizontal="true"
android:layout_marginTop="25dp"
android:text="CountDownTimer获取验证码" />
<TextView
android:id="@+id/tv_show_h"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="178dp"
android:text="Handler获取验证码" />
</RelativeLayout>
package com.example.hlqcountdowntimer;
import android.app.Activity;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.TextView;
public class MainActivity extends Activity {
private TextView tvShowH, tvShowC;
private Handler handler = new Handler() {
public void handleMessage(Message msg) {
tvShowH.setText(msg.what - 1 + "s");
if (msg.what == 0) {
// 倒计时结束让按钮可用
tvShowH.setEnabled(true);
tvShowH.setText("Handler获取验证码");
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tvShowH = (TextView) findViewById(R.id.tv_show_h);
tvShowH.setOnClickListener(listenerH);
tvShowC = (TextView) findViewById(R.id.tv_show_c);
tvShowC.setOnClickListener(listenerC);
}
private OnClickListener listenerH = new View.OnClickListener() {
@Override
public void onClick(View v) {
tvShowH.setEnabled(false);
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 10; i >= 0; i--) {
handler.sendEmptyMessage(i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
}
};
private OnClickListener listenerC = new View.OnClickListener() {
@Override
public void onClick(View v) {
tvShowC.setEnabled(false);
timer.start();
}
};
private CountDownTimer timer = new CountDownTimer(10000, 1000) {
@Override
public void onTick(long millisUntilFinished) {
long time = millisUntilFinished / 1000;
if (time == 0) {
tvShowC.setText(time + "秒后可重发");
onFinish();
}
tvShowC.setText(time + "秒后可重发");
}
@Override
public void onFinish() {
tvShowC.setEnabled(true);
tvShowC.setText("CountDownTimer获取验证码");
}
};
}
package com.example.hlqcountdowntimer.weight;
import android.os.Handler;
import android.os.Message;
import android.os.SystemClock;
import android.widget.TextView;
public abstract class CountDownTimer {
private final TextView test;
/**
* 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;
/**
* boolean representing if the timer was cancelled
*/
private boolean mCancelled = false;
/**
* @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(TextView test, long millisInFuture, long countDownInterval) {
this.test = test;
mMillisInFuture = millisInFuture;
mCountdownInterval = countDownInterval;
}
/**
* Cancel the countdown.
*/
public synchronized final void cancel() {
mCancelled = true;
mHandler.removeMessages(MSG);
}
/**
* Start the countdown.
*/
public synchronized final CountDownTimer start() {
mCancelled = false;
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 void onTick(long millisUntilFinished) {
long time = millisUntilFinished / 1000;
test.setText(time + "秒后可重发");
};
/**
* Callback fired when the time is up.
*/
public void onFinish() {
test.setEnabled(true);
test.setText("试试吧");
};
private static final int MSG = 1;
// handles counting down
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);
}
}
}
};
}