博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【安卓基础】倒计时按钮封装(验证码倒计时按钮)
阅读量:4573 次
发布时间:2019-06-08

本文共 4800 字,大约阅读时间需要 16 分钟。

验证码按钮在项目的使用频率应该是100%,现在大多数应用都会采用手机号码登陆,通常都会支持发送验证码登陆的功能。

我在项目中也遇到这样的功能,特别在忘记密码的界面,我注意到一点:当发送验证码之后,要60秒之后才能再发,如果退出界面,重新进入同样需要等待时间结束。

其中分析一下流程应该是这样的:

  1. 倒计时按钮点击:发送验证码
  2. 发送验证码成功:禁用按钮 & 倒计时开始
  3. 倒计时结束之后:恢复按钮

针对这种场景进行分析,如果采用继承Button的方式对项目耦合性太强了,以后不需要移除也特别麻烦。所以抽象一个工具类进行对Button自动化设置会更好,以后不需要了可以随时移除然后重新实现逻辑。

既然是倒计时功能,所以项目需要使用到相关的技术,在安卓开发中,我总结了如下几种倒计时方法:

  1. Handler实现倒计时(sendEmptyMessageDelayed方法)
  2. Thread实现倒计时
  3. View.postDelayed()实现倒计时
  4. CountDownTimer实现倒计时

CountDownTimer是安卓专门未倒计时设计的一个类,使用起来也非常方便,所以我也选择它作为实现的基础。他是一个抽象类,使用时需要继承并实现onTick()和onFinish()方法。

/** * 构造函数(millisInFuture:倒计时总时间,countDownInterval:触发回调的时间间隔) */public CountDownTimer(long millisInFuture, long countDownInterval)/** * 每次倒计时都会触发回调,millisUntilFinished表示剩余的时间。 */public abstract void onTick(long millisUntilFinished);/** * 倒计时结束后回调 */public abstract void onFinish();

再想想自己设计这个工具类的具体思想:

  1. autoHandleWhenActivityCreate(Button indicator) :在onCreate()中调用,绑定按钮并初始化。
  2. autoHandleWhenActivityDestroy() :在onDestroy()中调用,因为CountDownTimer本质上是Handler实现的,所以处理不当会造成内存泄漏。
  3. autoHandleRequestStartTimer() :调用此方法会立即开始倒计时,按钮的倒计时文字将会变化。

贴一贴工具类的具体使用方法:

public class ForgetActivity extends AppCompatActivity {    Button uaSendCode;    // 第一步:创建静态计时器类(当前界面有效,重复进入倒计时依然继续)    private static CountDownTimer mCountDown = new CountDownTimer(60, "发送验证码(%s)", "发送验证码", R.drawable.register_bg_send, R.drawable.register_bg_unsend);    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.forget_activity_main);        uaSendCode = findViewById(R.id.uaSendCode);        // 第二步:绑定按钮        mCountDown.autoHandleWhenActivityCreate(uaSendCode);                        uaSendCode.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                // 注意:启动计时器需要调用下面的方法                mCountDown.autoHandleRequestStartTimer();            }        });    }        @Override    protected void onDestroy() {        super.onDestroy();        //第三步:释放内部引用,防止内存泄漏        mCountDown.autoHandleWhenActivityDestroy();    }}

下面贴上具体实现的逻辑:

package com.anbang.family.library;import android.view.View;import android.widget.Button;/** * 按钮倒计时 */public class CountDownTimer extends android.os.CountDownTimer {    private Button mIndicator;    private String mCountDownFormatString = "发送验证码(%s)";    private String mCountDownFinishString = "发送验证码";    private int mEnableDrawable;    private int mUnableDrawable;    private int mSecond;    private int mCount;    /**     * 是否启动过计时器(mCount一开始不为0,所以配合这个标志做判断是否start计时器)     */    private boolean mAlreadyStart = false;    public CountDownTimer(int second, String countDownFormatString, String countDownFinishString, int enableDrawable, int unableDrawable) {        super((second <= 0 ? 60 : second) * 1000, 1000);        this.mSecond = second;        this.mCount = second;        this.mCountDownFormatString = countDownFormatString;        this.mCountDownFinishString = countDownFinishString;        this.mEnableDrawable = enableDrawable;        this.mUnableDrawable = unableDrawable;    }    public int getmCount() {        return mCount;    }    public void autoHandleWhenActivityCreate(Button indicator) {        this.mIndicator = indicator;        if (mCount <= 0 || !mAlreadyStart) {            mIndicator.setEnabled(true);            mIndicator.setText(mCountDownFinishString);            mIndicator.setBackgroundResource(mEnableDrawable);        } else {            mIndicator.setEnabled(false);            mIndicator.setBackgroundResource(mUnableDrawable);            mIndicator.setText(String.format(mCountDownFormatString, mCount));        }    }    public void autoHandleWhenActivityDestroy() {        mIndicator = null;    }    public void autoHandleRequestStartTimer() {        if (mCount <= 0 || !mAlreadyStart) {            mAlreadyStart = true;            mCount = mSecond <= 0 ? 60 : mSecond;            if (mIndicator != null) {                unableIndicator(mCount);            }            start();        }    }    @Override    public void onTick(long millisUntilFinished) {        mCount--;        unableIndicator((int) (millisUntilFinished / 1000));    }    @Override    public void onFinish() {        enableIndicator();    }    private void unableIndicator(int second) {        if (mIndicator != null) {            mIndicator.setEnabled(false);            mIndicator.setBackgroundResource(mUnableDrawable);            mIndicator.setText(String.format(mCountDownFormatString, second));        }    }    private void enableIndicator() {        if (mIndicator != null) {            mIndicator.setEnabled(true);            mIndicator.setText(mCountDownFinishString);            mIndicator.setBackgroundResource(mEnableDrawable);        }    }}

转载于:https://www.cnblogs.com/nicojerry/p/10350409.html

你可能感兴趣的文章
阶段1 语言基础+高级_1-3-Java语言高级_02-继承与多态_第1节 继承_13-Java继承的三个特点...
查看>>
阶段1 语言基础+高级_1-3-Java语言高级_05-异常与多线程_第1节 异常_14_自定义异常类的练习...
查看>>
第五周总结
查看>>
Poj 2328 Guessing Game(猜数字游戏)
查看>>
Hibernate基础知识
查看>>
20150518 字符设备驱动
查看>>
UIView的动画之初步学习
查看>>
中小企业实施OA的意义
查看>>
es6 数组
查看>>
JS判断是否在微信浏览器打开
查看>>
javascript中typeof和instanceof的区别
查看>>
数据结构-数组1
查看>>
jquery之别踩白块游戏的实现
查看>>
转载Eclipse中Maven WEB工程tomcat项目添加调试
查看>>
caller和callee的解析与使用-型参与实参的访问
查看>>
[转]JavaScript线程运行机制
查看>>
日期时间处理函数收集
查看>>
HDOJ树形DP专题之Anniversary party
查看>>
设计师 商业
查看>>
算法(例子)
查看>>