在目前许多应用中都会用到,输入手机号码,获取验证码,然后开始倒计时,这里主要功能点击“获取验证码”倒计时开始,在最后附上DEMO,demo效果图如下:

android之验证码倒计时_Android开发android之验证码倒计时_Android开发_02

这里是主界面代码:

public class MainActivity extends AppCompatActivity {

    private CountDownTimerButton get_ver_btn;
    private EditText username_et;
    private EditText vercode_et;
    private EditText pwd_et;
    private Button login_btn;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
        initCountDownBtn();
    }

    private void initCountDownBtn() {
        get_ver_btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                get_ver_btn.setStartCountDownText("再次获取");
                get_ver_btn.startCountDownTimer(60000,1000);
            }
        });
    }

    private void initView(){
        get_ver_btn=(CountDownTimerButton) findViewById(R.id.btn_get_ver);
        username_et=(EditText) findViewById(R.id.et_username);
        vercode_et=(EditText) findViewById(R.id.et_ver_code);
        pwd_et=(EditText) findViewById(R.id.et_pw);
        login_btn=(Button) findViewById(R.id.btn_submit);

    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        get_ver_btn.onDestroy();
    }

其他部分代码:

package com.example.administrator.countdowntimerbdemo.utils;

import android.os.Handler;
import android.os.Message;
import android.os.SystemClock;

/**
 * Created by abc on 2019/10/10.
 */

public abstract class CountDownTimer {
    /**
     * 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(long millisInFuture, long countDownInterval) {
        mMillisInFuture = millisInFuture-1;
        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 abstract void onTick(long millisUntilFinished);

    /**
     * Callback fired when the time is up.
     */
    public abstract void onFinish();


    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 {
                    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);
                }
            }
        }
    };
}

这里是自定义代码:

package com.example.administrator.countdowntimerbdemo.widget;

import android.content.Context;
import android.graphics.Color;
import android.graphics.drawable.GradientDrawable;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;

import com.example.administrator.countdowntimerbdemo.R;
import com.example.administrator.countdowntimerbdemo.utils.TimerUtil;


/**
 * Created by abc on 2019/10/10.
 */

public class CountDownTimerButton extends android.support.v7.widget.AppCompatButton {

    private final String TAG = CountDownTimerButton.class.getSimpleName();
    private final int STATE_STARTCOUNT = 0;
    private final int STATE_STOPCOUNT = 1;
    private String startCountDownStateColor;
    private String stopCountDownStateColor;
    private String startCountDownText;
    private String stopCountDownText;
    private TimerUtil mTimerUtil;
    private CountDownStateChangeListener mCountDownStateChangeListener;
    public interface CountDownStateChangeListener{
        void onStartCount(long millsUtilFinished);
        void onFinishCount();
    }

    public CountDownTimerButton(Context context) {
        this(context, null);
    }

    public CountDownTimerButton(Context context, AttributeSet attrs) {
        this(context, attrs, R.attr.buttonStyle);
    }

    public CountDownTimerButton(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
//        changeBackGroundColor(STATE_STOPCOUNT);

    }

    public void onDestroy() {
        Log.d(TAG, "run in onDestroy,currentTimeMillis: " + System.currentTimeMillis());
        if (mTimerUtil != null) {
            mTimerUtil.cancel();
            mTimerUtil = null;
        }
        initState();
    }

    private void initState() {
        changeBackGroundColor(STATE_STOPCOUNT);
        setClickable(true);
        setText(stopCountDownText);
    }

    public void setCountDownStateChangeListener(CountDownStateChangeListener listener){
        mCountDownStateChangeListener=listener;
    }

    public void setStartCountDownStateColor(String color) {
        startCountDownStateColor = color;
    }

    public void setStopCountDownColor(String color) {
        stopCountDownStateColor = color;
    }

    public void setStartCountDownText(String startCountDownText) {
        this.startCountDownText = startCountDownText;
    }

    private void setStopCountDownText(String stopCountDownText) {
        this.stopCountDownText = stopCountDownText;
    }

    public void startCountDownTimer(final long millisInFuture, final long countDownInterval) {
        if (mTimerUtil != null) {
            mTimerUtil.cancel();
            mTimerUtil = null;
        }
        setStopCountDownText(getText().toString());
        mTimerUtil = new TimerUtil(millisInFuture, countDownInterval);
        mTimerUtil.setCountDownTimerListener(new TimerUtil.CountDownTimerListener() {
            @Override
            public void startCount(long millsUtilFinished) {
                if (mCountDownStateChangeListener!=null){
                    mCountDownStateChangeListener.onStartCount(millsUtilFinished);
                    return;
                }
                changeBackGroundColor(STATE_STARTCOUNT);
                setClickable(false);
                setText(startCountDownText+"(" + millsUtilFinished / 1000 + ")");
            }

            @Override
            public void finishCount() {
                if (mCountDownStateChangeListener!=null){
                    mCountDownStateChangeListener.onFinishCount();
                    return;
                }
                setText(stopCountDownText);
                setClickable(true);
                changeBackGroundColor(STATE_STOPCOUNT);
            }
        });
        mTimerUtil.start();
    }

    private void changeBackGroundColor(int state) {
        try {
            GradientDrawable drawable = (GradientDrawable) getBackground();
            switch (state) {
                case STATE_STARTCOUNT:
                    if (TextUtils.isEmpty(startCountDownStateColor)) {
                        drawable.setColor(Color.parseColor("#d3d2d6"));
                    } else {
                        drawable.setColor(Color.parseColor(startCountDownStateColor));
                    }
                    break;
                case STATE_STOPCOUNT:
                    if (TextUtils.isEmpty(stopCountDownStateColor)) {
                        drawable.setColor(Color.parseColor("#ffffff"));
                    } else {
                        drawable.setColor(Color.parseColor(stopCountDownStateColor));
                    }
                    break;
                default:
                    break;
            }
        } catch (ClassCastException e) {
            e.fillInStackTrace();
        }

    }


}

以上就是部分代码,需要看详细代码。

CSDN:下载

GIT:下载

短信验证码自动填充输入框