Android 验证码倒计时两种方案
使用
第一种方案:自定义控件
1.在布局中使用
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:gravity="center" android:layout_height="match_parent"> <com.ywj.countdowntextviewdemo.CountDownTextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/countDownTextView" android:text="Hello World!" /> </RelativeLayout>
2.在Activity中获取控件使用
CountDownTextView countDownTextView = (CountDownTextView) findViewById(R.id.countDownTextView); countDownTextView.setCountDownMillis(5000); countDownTextView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Log.e("MainActivity","点击事件"); } }); countDownTextView.start();
3.CountDownTextView.java
import android.content.Context; import android.os.Handler; import android.os.Message; import android.support.annotation.ColorRes; import android.support.annotation.Nullable; import android.util.AttributeSet; import android.util.Log; import android.view.View; import android.widget.TextView; /** * 倒计时TextView * Created by weijing on 2017-08-21 14:43. */ public class CountDownTextView extends TextView { /** * 提示文字 */ private String mHintText = "重新发送"; /** * 倒计时时间 */ private long mCountDownMillis = 60_000; /** * 剩余倒计时时间 */ private long mLastMillis; /** * 间隔时间差(两次发送handler) */ private long mIntervalMillis = 1_000; /** * 开始倒计时code */ private final int MSG_WHAT_START = 10_010; /** * 可用状态下字体颜色Id */ private int usableColorId = android.R.color.holo_blue_light; /** * 不可用状态下字体颜色Id */ private int unusableColorId = android.R.color.darker_gray; public CountDownTextView(Context context) { super(context); } public CountDownTextView(Context context, @Nullable AttributeSet attrs) { super(context, attrs); } public CountDownTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } private Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); switch (msg.what) { case MSG_WHAT_START: // Log.e("l", mLastMillis + ""); if (mLastMillis > 0) { setUsable(false); mLastMillis -= mIntervalMillis; mHandler.sendEmptyMessageDelayed(MSG_WHAT_START, mIntervalMillis); } else { setUsable(true); } break; } } }; /** * 设置是否可用 * * @param usable */ public void setUsable(boolean usable) { if (usable) { //可用 if (!isClickable()) { setClickable(usable); setTextColor(getResources().getColor(usableColorId)); setText(mHintText); } } else { //不可用 if (isClickable()) { setClickable(usable); setTextColor(getResources().getColor(unusableColorId)); } setText(mLastMillis / 1000 + "秒后" + mHintText); } } /** * 设置倒计时颜色 * * @param usableColorId 可用状态下的颜色 * @param unusableColorId 不可用状态下的颜色 */ public void setCountDownColor(@ColorRes int usableColorId, @ColorRes int unusableColorId) { this.usableColorId = usableColorId; this.unusableColorId = unusableColorId; } /** * 设置倒计时时间 * * @param millis 毫秒值 */ public void setCountDownMillis(long millis) { mCountDownMillis = millis; } /** * 开始倒计时 */ public void start() { mLastMillis = mCountDownMillis; mHandler.sendEmptyMessage(MSG_WHAT_START); } /** * 重置倒计时 */ public void reset() { mLastMillis = 0; mHandler.sendEmptyMessage(MSG_WHAT_START); } @Override public void setOnClickListener(@Nullable final OnClickListener onClickListener) { super.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { mHandler.removeMessages(MSG_WHAT_START); start(); onClickListener.onClick(v); } }); } @Override protected void onDetachedFromWindow() { super.onDetachedFromWindow(); mHandler.removeMessages(MSG_WHAT_START); } }
第二种方案:工具类
1.在activity中使用
TextView textView = (TextView) findViewById(R.id.textView); new CountDownUtil(textView) .setCountDownMillis(60_000L)//倒计时60000ms .setCountDownColor(android.R.color.holo_blue_light,android.R.color.darker_gray)//不同状态字体颜色 .setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Log.e("MainActivity","发送成功"); } }) .start();
2.CountDownUtil.java
import android.os.Handler; import android.os.Message; import android.support.annotation.ColorRes; import android.support.annotation.Nullable; import android.view.View; import android.widget.TextView; import java.lang.ref.WeakReference; /** * 倒计时工具 * Created by weijing on 2017-08-22 11:50. */ public class CountDownUtil { /** * 开始倒计时code */ private final int MSG_WHAT_START = 10_010; /** * 弱引用 */ private WeakReference<TextView> mWeakReference; /** * 倒计时时间 */ private long mCountDownMillis = 60_000; /** * 提示文字 */ private String mHintText = "重新发送"; /** * 剩余倒计时时间 */ private long mLastMillis; /** * 间隔时间差(两次发送handler) */ private long mIntervalMillis = 1_000; /** * 可用状态下字体颜色Id */ private int usableColorId = android.R.color.holo_blue_light; /** * 不可用状态下字体颜色Id */ private int unusableColorId = android.R.color.darker_gray; private Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); switch (msg.what) { case MSG_WHAT_START: if (mLastMillis > 0) { setUsable(false); mLastMillis -= mIntervalMillis; if (mWeakReference.get() != null) { mHandler.sendEmptyMessageDelayed(MSG_WHAT_START, mIntervalMillis); } } else { setUsable(true); } break; } } }; public CountDownUtil(TextView textView) { mWeakReference = new WeakReference<>(textView); } public CountDownUtil(TextView textView, long countDownMillis) { mWeakReference = new WeakReference<>(textView); this.mCountDownMillis = countDownMillis; } public CountDownUtil setCountDownMillis(long countDownMillis) { this.mCountDownMillis = countDownMillis; return this; } /** * 设置是否可用 * * @param usable */ private void setUsable(boolean usable) { TextView mTextView = mWeakReference.get(); if (mTextView != null) { if (usable) { //可用 if (!mTextView.isClickable()) { mTextView.setClickable(usable); mTextView.setTextColor(mTextView.getResources().getColor(usableColorId)); mTextView.setText(mHintText); } } else { //不可用 if (mTextView.isClickable()) { mTextView.setClickable(usable); mTextView.setTextColor(mTextView.getResources().getColor(unusableColorId)); } String content = mLastMillis / 1000 + "秒后" + mHintText; mTextView.setText(content); } } } /** * 设置倒计时颜色 * * @param usableColorId 可用状态下的颜色 * @param unusableColorId 不可用状态下的颜色 */ public CountDownUtil setCountDownColor(@ColorRes int usableColorId, @ColorRes int unusableColorId) { this.usableColorId = usableColorId; this.unusableColorId = unusableColorId; return this; } /** * 开始倒计时 */ public CountDownUtil start() { mLastMillis = mCountDownMillis; mHandler.sendEmptyMessage(MSG_WHAT_START); return this; } public CountDownUtil setOnClickListener(@Nullable final View.OnClickListener onClickListener) { TextView mTextView = mWeakReference.get(); if (mTextView != null) mTextView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { mHandler.removeMessages(MSG_WHAT_START); start(); onClickListener.onClick(v); } }); return this; } /** * 重置停止倒计时 */ public CountDownUtil reset() { mLastMillis = 0; mHandler.sendEmptyMessage(MSG_WHAT_START); return this; }
TextView textView = (TextView) findViewById(R.id.textView); new CountDownUtil(textView) .setCountDownMillis(60_000L)//倒计时60000ms .setCountDownColor(android.R.color.holo_blue_light,android.R.color.darker_gray)//不同状态字体颜色 .setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Log.e("MainActivity","发送成功"); } }) .start();