1. 程式人生 > >Android 驗證碼倒計時兩種方案

Android 驗證碼倒計時兩種方案

ans net ive gray remove public handler RM -s

技術分享圖片

使用

第一種方案:自定義控件

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

Android 驗證碼倒計時兩種方案