最近有朋友问我如何实现短信验证功能,还特意强调了验证码发送按钮的倒计时问题,其实这些都是些很基础的问题,但既然写了,也不妨贴出来,权当记录。
好了,既然是基础,那话不多说,上代码。
第一种实现方式:自定义倒计时类,实现Runnable接口
- public class MainActivity extends AppCompatActivity implements View.OnClickListener {
- private Button timeBtn;
- public int T = 10; //倒计时时长
- private Handler mHandler = new Handler();
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- timeBtn = (Button) findViewById(R.id.timeBtn);
- timeBtn.setOnClickListener(this);
- }
- @Override
- public void onClick(View view) {
- switch (view.getId()){
- case R.id.timeBtn:
- new Thread(new MyCountDownTimer()).start(); //开始执行
- break;
- }
- }
- /**
- * 自定义倒计时类,实现Runnable接口
- */
- class MyCountDownTimer implements Runnable{
- @Override
- public void run() {
- //倒计时开始,循环
- while (T > 0) {
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- timeBtn.setClickable(false);
- timeBtn.setText(T + "秒后重新开始");
- }
- });
- try {
- Thread.sleep(1000); //强制线程休眠1秒,就是设置倒计时的间隔时间为1秒。
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- T--;
- }
- //倒计时结束,也就是循环结束
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- timeBtn.setClickable(true);
- timeBtn.setText("倒计时开始");
- }
- });
- T = 10; //最后再恢复倒计时时长
- }
- }
- }
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private Button timeBtn;
public int T = 10; //倒计时时长
private Handler mHandler = new Handler();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
timeBtn = (Button) findViewById(R.id.timeBtn);
timeBtn.setOnClickListener(this);
}
@Override
public void onClick(View view) {
switch (view.getId()){
case R.id.timeBtn:
new Thread(new MyCountDownTimer()).start();//开始执行
break;
}
}
/**
* 自定义倒计时类,实现Runnable接口
*/
class MyCountDownTimer implements Runnable{
@Override
public void run() {
//倒计时开始,循环
while (T > 0) {
mHandler.post(new Runnable() {
@Override
public void run() {
timeBtn.setClickable(false);
timeBtn.setText(T + "秒后重新开始");
}
});
try {
Thread.sleep(1000); //强制线程休眠1秒,就是设置倒计时的间隔时间为1秒。
} catch (InterruptedException e) {
e.printStackTrace();
}
T--;
}
//倒计时结束,也就是循环结束
mHandler.post(new Runnable() {
@Override
public void run() {
timeBtn.setClickable(true);
timeBtn.setText("倒计时开始");
}
});
T = 10; //最后再恢复倒计时时长
}
}
}
效果展示:
第二种实现方式:自定义Button
- public class CountDownTimerButton extends Button implements View.OnClickListener {
- private Context mContext;
- private OnClickListener mOnClickListener;
- private Timer mTimer;//调度器
- private TimerTask mTask;
- private long duration = 10000;//倒计时时长 设置默认10秒
- private long temp_duration;
- private String clickBeffor = "倒计时开始";//点击前
- private String clickAfter = "秒后重新开始";//点击后
- public CountDownTimerButton(Context context) {
- super(context);
- mContext = context;
- setOnClickListener(this);
- }
- public CountDownTimerButton(Context context, AttributeSet attrs) {
- super(context, attrs);
- mContext = context;
- setOnClickListener(this);
- }
- private Handler mHandler = new Handler(){
- @Override
- public void handleMessage(Message msg) {
- CountDownTimerButton.this.setText(temp_duration/1000 + clickAfter);
- temp_duration -= 1000;
- if (temp_duration < 0) {//倒计时结束
- CountDownTimerButton.this.setEnabled(true);
- CountDownTimerButton.this.setText(clickBeffor);
- stopTimer();
- }
- }
- };
- @Override
- public void setOnClickListener(OnClickListener onClickListener) {//提供外部访问方法
- if (onClickListener instanceof CountDownTimerButton) {
- super.setOnClickListener(onClickListener);
- }else{
- this.mOnClickListener = onClickListener;
- }
- }
- @Override
- public void onClick(View view) {
- if (mOnClickListener != null) {
- mOnClickListener.onClick(view);
- }
- startTimer();
- }
- //计时开始
- private void startTimer(){
- temp_duration = duration;
- CountDownTimerButton.this.setEnabled(false);
- mTimer = new Timer();
- mTask = new TimerTask() {
- @Override
- public void run() {
- mHandler.sendEmptyMessage(0x01);
- }
- };
- mTimer.schedule(mTask, 0, 1000);//调度分配,延迟0秒,时间间隔为1秒
- }
- //计时结束
- private void stopTimer(){
- if (mTask != null) {
- mTask.cancel();
- mTask = null;
- }
- if (mTimer != null) {
- mTimer.cancel();
- mTimer = null;
- }
- }
- }
public class CountDownTimerButton extends Button implements View.OnClickListener {
private Context mContext;
private OnClickListener mOnClickListener;
private Timer mTimer;//调度器
private TimerTask mTask;
private long duration = 10000;//倒计时时长 设置默认10秒
private long temp_duration;
private String clickBeffor = "倒计时开始";//点击前
private String clickAfter = "秒后重新开始";//点击后
public CountDownTimerButton(Context context) {
super(context);
mContext = context;
setOnClickListener(this);
}
public CountDownTimerButton(Context context, AttributeSet attrs) {
super(context, attrs);
mContext = context;
setOnClickListener(this);
}
private Handler mHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
CountDownTimerButton.this.setText(temp_duration/1000 + clickAfter);
temp_duration -= 1000;
if (temp_duration < 0) {//倒计时结束
CountDownTimerButton.this.setEnabled(true);
CountDownTimerButton.this.setText(clickBeffor);
stopTimer();
}
}
};
@Override
public void setOnClickListener(OnClickListener onClickListener) {//提供外部访问方法
if (onClickListener instanceof CountDownTimerButton) {
super.setOnClickListener(onClickListener);
}else{
this.mOnClickListener = onClickListener;
}
}
@Override
public void onClick(View view) {
if (mOnClickListener != null) {
mOnClickListener.onClick(view);
}
startTimer();
}
//计时开始
private void startTimer(){
temp_duration = duration;
CountDownTimerButton.this.setEnabled(false);
mTimer = new Timer();
mTask = new TimerTask() {
@Override
public void run() {
mHandler.sendEmptyMessage(0x01);
}
};
mTimer.schedule(mTask, 0, 1000);//调度分配,延迟0秒,时间间隔为1秒
}
//计时结束
private void stopTimer(){
if (mTask != null) {
mTask.cancel();
mTask = null;
}
if (mTimer != null) {
mTimer.cancel();
mTimer = null;
}
}
}
对应的Activity文件
- public class MainActivity extends AppCompatActivity{
- private CountDownTimerButton timeBtn;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_maind);
- timeBtn = (CountDownTimerButton) findViewById(R.id.timeBtn);
- timeBtn.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- Toast.makeText(ThirdActivity.this, "倒计时开始", Toast.LENGTH_SHORT).show();
- }
- });
- }
- }
public class MainActivity extends AppCompatActivity{
private CountDownTimerButton timeBtn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maind);
timeBtn = (CountDownTimerButton) findViewById(R.id.timeBtn);
timeBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(ThirdActivity.this, "倒计时开始", Toast.LENGTH_SHORT).show();
}
});
}
}
对应的xml文件
- <?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"
- 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="com.hbh.cl.countdowntimerdemo.MainActivity">
- <com.hbh.cl.view.CountDownTimerButton
- android:id="@+id/timeBtn"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:text="@string/start"/>
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_below="@id/timeBtn"
- android:text="Third Activity"/>
- </RelativeLayout>
<?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"
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="com.hbh.cl.countdowntimerdemo.MainActivity">
<com.hbh.cl.view.CountDownTimerButton
android:id="@+id/timeBtn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/start"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/timeBtn"
android:text="Third Activity"/>
</RelativeLayout>
效果展示:
第三种实现方式:使用 CountDownTimer
- public class MainActivity extends AppCompatActivity implements View.OnClickListener {
- private Button timeBtn;
- private CountDownTime mTime;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- timeBtn = (Button) findViewById(R.id.timeBtn);
- timeBtn.setOnClickListener(this);
- mTime = new CountDownTime(10000, 1000); //初始化对象
- }
- @Override
- public void onClick(View view) {
- switch (view.getId()){
- case R.id.timeBtn:
- mTime.start(); //开始计时
- break;
- }
- }
- /**
- * 第一种方法 使用android封装好的 CountDownTimer
- * 创建一个类继承 CountDownTimer
- */
- class CountDownTime extends CountDownTimer{
- //构造函数 第一个参数代表总的计时时长 第二个参数代表计时间隔 单位都是毫秒
- public CountDownTime(long millisInFuture, long countDownInterval) {
- super(millisInFuture, countDownInterval);
- }
- @Override
- public void onTick(long l) { //每计时一次回调一次该方法
- timeBtn.setClickable(false);
- timeBtn.setText(l/1000 + "秒后重新开始");
- }
- @Override
- public void onFinish() { //计时结束回调该方法
- timeBtn.setClickable(true);
- timeBtn.setText("倒计时开始");
- }
- }
- }
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private Button timeBtn;
private CountDownTime mTime;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
timeBtn = (Button) findViewById(R.id.timeBtn);
timeBtn.setOnClickListener(this);
mTime = new CountDownTime(10000, 1000);//初始化对象
}
@Override
public void onClick(View view) {
switch (view.getId()){
case R.id.timeBtn:
mTime.start(); //开始计时
break;
}
}
/**
* 第一种方法 使用android封装好的 CountDownTimer
* 创建一个类继承 CountDownTimer
*/
class CountDownTime extends CountDownTimer{
//构造函数 第一个参数代表总的计时时长 第二个参数代表计时间隔 单位都是毫秒
public CountDownTime(long millisInFuture, long countDownInterval) {
super(millisInFuture, countDownInterval);
}
@Override
public void onTick(long l) { //每计时一次回调一次该方法
timeBtn.setClickable(false);
timeBtn.setText(l/1000 + "秒后重新开始");
}
@Override
public void onFinish() { //计时结束回调该方法
timeBtn.setClickable(true);
timeBtn.setText("倒计时开始");
}
}
}
效果展示:
代码全都贴上了,都有注释,不说了,下班