Android实现倒计时的按钮的示例代码
作者:lxn_李小牛 发布时间:2021-10-17 14:45:11
标签:android,倒计时
最近有人问我如何实现倒计时的按钮功能,例如发送验证码,我记得有个CountDownTimer,因为好久没用过了,自己就写了一个,代码如下
new CountDownTimer(10000, 1000) {
@Override
public void onTick(long millisUntilFinished) {
btn2.setEnabled(false);
btn2.setText(String.format("%ds后重新发送验证码",millisUntilFinished/1000));
}
@Override
public void onFinish() {
btn2.setEnabled(true);
btn2.setText("发送验证码");
}
}.start();
点击按钮后开始倒计时,貌似很简单啊,但是运行起来发现有一些问题,先给大家看效果图
我们打印一下时间
这里我们可以看到8这个秒数没有出现,并且最后1秒的时间有些长,每次点击开始倒计时的时候偶尔就会出现少一个数字的问题,所以说这个东西是不精确的,网上也有很多人再说,那么有没有其他的实现思路呢?这里我们来自定义一个倒计时的按钮
public class TimeButton extends Button implements View.OnClickListener {
private long length = 60 * 1000;// 倒计时长度,这里给了默认60秒
private String textafter = "秒后重新获取";
private String textbefore = "点击获取验证码";
private final String TIME = "time";
private final String CTIME = "ctime";
private OnClickListener mOnclickListener;
private Timer t;
private TimerTask tt;
private long time;
private Context mContext;
Map<String, Long> map = new HashMap<String, Long>();
public TimeButton(Context context) {
super(context);
setOnClickListener(this);
}
public TimeButton(Context context, AttributeSet attrs) {
super(context, attrs);
mContext = context;
setOnClickListener(this);
}
@SuppressLint("HandlerLeak")
Handler han = new Handler() {
public void handleMessage(android.os.Message msg) {
TimeButton.this.setText(time / 1000 + textafter);
time -= 1000;
if (time < 0) {
TimeButton.this.setEnabled(true);
TimeButton.this.setText(textbefore);
clearTimer();
}
}
};
private void initTimer() {
time = length;
t = new Timer();
tt = new TimerTask() {
@Override
public void run() {
Log.e("yung", time / 1000 + "");
han.sendEmptyMessage(0x01);
}
};
}
private void clearTimer() {
Toast.makeText(mContext, "计时结束", Toast.LENGTH_SHORT).show();
if (tt != null) {
tt.cancel();
tt = null;
}
if (t != null)
t.cancel();
t = null;
}
@Override
public void setOnClickListener(OnClickListener l) {
if (l instanceof TimeButton) {
super.setOnClickListener(l);
} else
this.mOnclickListener = l;
}
@Override
public void onClick(View v) {
if (mOnclickListener != null)
mOnclickListener.onClick(v);
initTimer();
this.setText(time / 1000 + textafter);
this.setEnabled(false);
t.schedule(tt, 0, 1000);
}
/**
* 和activity的onDestroy()方法同步
*/
public void onDestroy() {
if (MainActivity.map == null)
MainActivity.map = new HashMap<String, Long>();
MainActivity.map.put(TIME, time);
MainActivity.map.put(CTIME, System.currentTimeMillis());
clearTimer();
}
/**
* 和activity的onCreate()方法同步
*/
public void onCreate(Bundle bundle) {
Log.e("yung", MainActivity.map + "");
if (MainActivity.map == null)
return;
if (MainActivity.map.size() <= 0)// 这里表示没有上次未完成的计时
return;
long time = System.currentTimeMillis() - MainActivity.map.get(CTIME)
- MainActivity.map.get(TIME);
MainActivity.map.clear();
if (time > 0)
return;
else {
initTimer();
this.time = Math.abs(time);
t.schedule(tt, 0, 1000);
this.setText(time + textafter);
this.setEnabled(false);
}
}
/**
* 设置计时时候显示的文本
*/
public TimeButton setTextAfter(String text1) {
this.textafter = text1;
return this;
}
/**
* 设置点击之前的文本
*/
public TimeButton setTextBefore(String text0) {
this.textbefore = text0;
this.setText(textbefore);
return this;
}
/**
* 设置到计时长度
*
* @param lenght 时间 默认毫秒
* @return
*/
public TimeButton setLenght(long lenght) {
this.length = lenght;
return this;
}
}
来源:http://blog.csdn.net/small_lee/article/details/51272874


猜你喜欢
- 线程池无限制的创建线程若采用"为每个任务分配一个线程"的方式会存在一些缺陷,尤其是当需要创建大量线程时:线程生命周期的开
- 本文实例为大家分享了ToolBar的使用方法,供大家参考,具体内容如下ToolBar时应用的标准工具栏;用来替代ActionBar;使用To
- 对象重复是指对象里面的变量的值都相等,并不定是地址。list集合存储的类型是基础类型还比较好办,直接把list集合转换成set集合就会自动去
- Spring-boot目的Spring是为了解决企业应用开发的复杂性而创建的,简化开发Spring如何简化开发1.基于POJO的轻量级和最小
- 0x00 关于AndroidManifest.xmlAndroidManifest.xml 是每个android程序中必须的文件。它位于整个
- 视频演示:springboot+vue音乐网站摘要网络技术以及计算机的发展,网友们对网络的要求也日益长高,平常在网上听话用一大堆下载软件下载
- 功能介绍功能:群聊+私发+上线提醒+下线提醒+查询在线用户文件Utils需要用maven导入下面两个包 <dependency>
- 一、简介Join方法主要是用来阻塞调用线程,直到某个线程终止或经过了指定时间为止。官方的解释比较乏味,通俗的说就是创建一个子线程,给它加了这
- 1.docker安装seata 1.3.0镜像docker pull seataio/seata-server:1.3.02.运行容器获取配
- 关于注入数据说明1.不通过配置文件注入数据通过@Value将外部的值动态注入到Bean中,使用的情况有:注入普通字符串注入操作系统属性注入表
- 介绍在本文中,我们将了解如何将现有应用程序迁移到Spring 6以及如何充分利用此升级。本文中的提示基于我在Hypersistence Op
- 算法分析一个排序算法的好坏,一般是通过下面几个关键信息来分析的,下面先介绍一下这几个关键信息,然后再将常见的排序算法的这些关键信息统计出来。
- 实例如下:import java.util.concurrent.CountDownLatch;import java.util.concu
- 本文实例讲述了Android通过json向MySQL中写入数据的方法。分享给大家供大家参考,具体如下:先说一下如何通过json将Androi
- jwt简介冒泡排序:(Bubble Sort)是一种简单的交换排序。之所以叫做冒泡排序,因为我们可以把每个元素当成一个小气泡,根据气泡大小,
- 本文实例讲述了C#实现HTTP上传文件的方法。分享给大家供大家参考。具体实现方法如下:发送文件代码如下:/// <summary>
- 一、简介Mybatis-Plus(简称MP)是一个 Mybatis 的一个增强工具,在 Mybatis 的基础上只做增强不做改变,为简化开发
- 在项目开发中,我们经常需要进行动态添加组件,其中可添加的部分有两项:布局和组件 其中,添加的布局主要有RelativeLayout
- 背景公司的一个服务需要做类似于分片的逻辑,一开始服务基于传统部署方式通过本地配置文件配置的方式就可以指定该机器服务的分片内容如:0,1,2,
- 本文实例讲述了C#根据反射和特性实现ORM 映射的方法。分享给大家供大家参考。具体如下:(一)关于反射什么是反射?反射就是在运行时,动态获取