Android实现获取验证码的倒计时功能

CountDownTimer

项目中经常用到倒计时的功能,比如说限时抢购,手机获取验证码等等。而google官方也帮我们封装好了一个类:CountDownTimer,使我们的开发更加方便。

CountDownTimer是一个抽象类,有两个抽象方法,它的API很简单:

public abstract void onTick(long millisUntilFinished);//这个是每次间隔指定时间的回调,millisUntilFinished:剩余的时间,单位毫秒
public abstract void onFinish();//这个是倒计时结束的回调

实现方式1

CountDownTimeUtil

public class CountDownTimeUtil {

    private WeakReference tvCodeWr;//控件软引用,防止内存泄漏

    private CountDownTimer timer;

    private int times = 60 * 1000;


    public CountDownTimeUtil(TextView textView) {
        super();
        this.tvCodeWr = new WeakReference(textView);
    }

    public void runTimer() {
        //倒计时的总时长   每次的间隔时间   单位都是毫秒
        timer = new CountDownTimer(times, 1000) {

            /**
             * 这个是倒计时结束的回调
             */
            @Override
            public void onFinish() {
                if (tvCodeWr.get() != null) {
                    tvCodeWr.get().setClickable(true);
                    tvCodeWr.get().setText("重新获取");
                    tvCodeWr.get().setTextColor(Color.parseColor("#ff0000"));
                }
                cancel();
            }

            /**
             * 这个是每次间隔指定时间的回调
             *
             * @param millisUntilFinished 剩余的时间,单位毫秒
             */
            @Override
            public void onTick(long millisUntilFinished) {
                if (tvCodeWr.get() != null) {
                    tvCodeWr.get().setClickable(false);
                    tvCodeWr.get().setText(millisUntilFinished / 1000 + "s后重新获取");
                    tvCodeWr.get().setTextColor(Color.parseColor("#666666"));
                }
            }
        }.start();
    }

    /**
     * 这个方法可以在activity或者fragment销毁的时候调用,防止内存泄漏
     * 如果在activity或者fragment关闭销毁的时候没有调用cancle方法,它的onTick方法还是会继续执行,这个时候UI控件都为空,不注意判断的话很容易空指针
     */
    public void cancel() {
        if (timer != null) {
            timer.onFinish();
            timer.cancel();
            timer = null;
        }
    }
}

获取验证码按钮布局

    

        

        
    

使用

public class MainActivity extends AppCompatActivity {


    private TextView mTvGetVerificationCode;

    private CountDownTimeUtil mCountDownTimeUtil;

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

        mTvGetVerificationCode = (TextView) findViewById(R.id.tv_get_verification_code);

        mTvGetVerificationCode.setOnClickListener(v -> {
            mCountDownTimeUtil = new CountDownTimeUtil(mTvGetVerificationCode);
            mCountDownTimeUtil.runTimer();
        });

    }

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

        if (mCountDownTimeUtil != null) {
            mCountDownTimeUtil.cancel();
        }
    }
}

实现方式2:自定义倒计时控件

CountDownText

/**
 * Cerated by xiaoyehai
 * Create date : 2020/12/31 14:28
 * description : 倒计时控件
 */
public class CountDownText extends AppCompatTextView {

    private CountDownTimer mCountDownTimer;
    /***
     * 持续时间毫秒
     */
    private int mTimeDuration ;
    /***
     * 间隔时间毫秒
     */
    private int mTimerGap ;

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

    public CountDownText(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public CountDownText(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.CountDownText);
        mTimeDuration = typedArray.getInt(R.styleable.CountDownText_millisDuration, 5000);
        mTimerGap = typedArray.getInt(R.styleable.CountDownText_millisGap, 1000);
        typedArray.recycle();
        initTimer();
        setText("获取验证码");
    }

    private void initTimer() {
        mCountDownTimer = new CountDownTimer(mTimeDuration + 500, mTimerGap) {
            @Override
            public void onTick(long millisUntilFinished) {
                setText(String.format("%ss后重新获取", millisUntilFinished / 1000));
                setEnabled(false);
                setTextColor(Color.parseColor("#333333"));
            }

            @Override
            public void onFinish() {
                setEnabled(true);
                setText("重新获取");
                setTextColor(Color.parseColor("#ff0000"));
            }
        };
    }


    public void start() {
        if (mCountDownTimer != null) {
            mCountDownTimer.start();
        }
    }

    private void end() {
        if (mCountDownTimer != null) {
            mCountDownTimer.cancel();
        }

    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        end();
        mCountDownTimer = null;
    }
}
    

        

        

    
public class MainActivity extends AppCompatActivity {

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

        CountDownText countDownText = (CountDownText) findViewById(R.id.cdt_get_verification_code);
        countDownText.setOnClickListener(v->countDownText.start());

    }
}

你可能感兴趣的:(Android实现获取验证码的倒计时功能)