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

原文地址:https://www.cnblogs.com/zhujiabin/p/9009508.html

时间: 2024-10-07 05:49:39

Android 验证码倒计时两种方案的相关文章

android环境下两种md5加密方式

在平时开发过程中,MD5加密是一个比较常用的算法,最常见的使用场景就是在帐号注册时,用户输入的密码经md5加密后,传输至服务器保存起来.虽然md5加密经常用,但是md5的加密原理我还真说不上来,对md5的认知目前仅仅停留在会使用的水平,想搞清楚还是要花点时间的,这是md5加密算法的相关介绍.本文主要介绍android平台下两种md5加密方式,分别为基于java语言的md5加密及ndk环境下基于c语言的md5加密. 下面代码为基于java语言的md5加密: public String getMD5

【SSH进阶之路】一步步重构容器实现Spring框架——解决容器对组件的“侵入式”管理的两种方案--主动查找和控制反转(九)

目录 [SSH进阶之路]一步步重构容器实现Spring框架--从一个简单的容器开始(八) [SSH进阶之路]一步步重构容器实现Spring框架--解决容器对组件的"侵入式"管理的两种方案--主动查找和控制反转(九) [SSH进阶之路]一步步重构容器实现Spring框架--配置文件+反射实现IoC容器(十)(未更新) [SSH进阶之路]一步步重构容器实现Spring框架--彻底封装,实现简单灵活的Spring框架(十一)(未更新) 对于IOC的原理,我们曾经写过一篇博文,[SSH进阶之路

HBase存储时间相关多列数据的两种方案

所谓“时间相关多列数据”指的是同一个Key下具有多个属性数据,并且这些数据与时间具有相关性,多数场景是该Key对应在不同时间时刻的行为数据.在实际应用中,这类数据很多,例如电子商务网站上用户最近一段时间浏览的宝贝集合.访问的URL列表等. 使用HBase存储此类数据时,有以下两种常用的方案: 多行单列 表结构设计 Row Key:用户标识ID + (Long.MAX_VALUE - timestamp) Column Family:’cf’ Column Qualifier:’’ Value:宝

PHP页面静态化:真静态的两种方案

---------------------------------------------------------------------------------------------- 方案1:如果静态文件存在,且生成时间30秒内,直接返回静态页面(有时间延迟)/*|------------------| <www.chenwei.ws>|------------------*/header('content-type:text/html;charset=utf-8'); $id = $_

Linux下实现秒级定时任务的两种方案

Linux下实现秒级定时任务的两种方案(Crontab 每秒运行): 第一种方案,当然是写一个后台运行的脚本一直循环,然后每次循环sleep一段时间. while true ;do command sleep XX //间隔秒数 done 第二种方案,使用crontab. 我们都知道crontab的粒度最小是到分钟,但是我们还是可以通过变通的方法做到隔多少秒运行一次. 以下方法将每20秒执行一次 crontab -e * * * * * /bin/date* * * * * sleep 20;

Linux系统中修改用户名的两种方案整理

在安装系统的时候,经常会无意识的随便起个用户名,后面如果发现该用户名不好或因为环境需要须重起个用户名,经过查找资料和亲自测试发现有两种方案可选:手动修改和使用usermod等命令自动修改. 方案一:手动修改各个关联用户文件 以root身份登录系统文件的修改需要root权限,这里不管是原root用户登录还是普通用户切换到root下都可以,只要有修改权限就行. 修改/etc/passwd这个文件中的用户名部分.用户组部分和主目录部分如我本来的用户名为hadoop,现在想修改为seed,则要修改下面部

apache两种方案三种方式实现反向代理tomcat

目录 1.概述 2.方案一:以proxy_module方式反向代理 3.方案二:以mod_jk方式反向代理 4.总结 1.概述 在前一博客(http://zhaochj.blog.51cto.com/368705/1639740)中实现了tomcat的在standalone模式下的部署,这样tomcat就身兼职两职,一方向要对http的请求作出响应,又要处理JSP程序,而处理http请求不是tomcat的强项,所以这样的请求就交给httpd.nginx这样的的专业处理http请求的套件来处理,而

java调用matlab函数接口的两种方案

Java 调用matlab 函数接口 Java调用matlab函数接口有两种方式: l 一种是通过matlab把函数打成jar包: l 一种是把matlab编译成dll后,用C++再封装成java能支持的数据类型的dll. 注意:不论用这两种方式中的哪一种,最终部署时都需要matlab环境(MCR,在matlab安装路径下有). 1. 方式一:matlab直接打jar包 1.1. 利用matlab自带工具打jar包 1.1.1. 建立jar包 在matlab的Commond Window中输入d

Android热修复:Andfix和Hotfix,两种方案的比较与实现

Andfix和hotfix是两种android热修复框架. android的热修复技术我看的最早的应该是QQ空间团队的解决方案,后来真正需要了,才仔细调查,现在的方案中,阿里有两种Dexposed和Andfix框架,由于前一种不支持5.0以上android系统,所以阿里系的方案我们就看Andfix就好.Hotfix框架算是对上文提到的QQ空间团队理论实现.本文旨在写实现方案,捎带原理. Andfix 引入 框架官网:https://github.com/alibaba/AndFix 介绍是用英文