热门标签 | HotTags
当前位置:  开发笔记 > Android > 正文

Android利用CountDownTimer实现验证码倒计时效果实例

这篇文章主要给大家介绍了关于Android如何利用CountDownTimer实现验证码倒计时效果的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧。

前言

等待总是让人感到焦急和厌烦的,特别是看不到进展的等待。所以为了不让用户痴痴地等,我们在进行某些耗时操作时,一般都要设计一个进度条或者倒计时器,让进度可视化,告诉用户“等待之后更精彩”。在使用短信验证码注册或者登录App就可以看到这样的设计:点击“发送验证码”的按钮之后,按钮上就会出现倒计时(一般为60秒),倒计时结束之后,按钮的文字就会变成“重新发送”。

在Android中要实现这样的效果可以使用Handler发送消息,但其实还有一个已经封装好的抽象类可以帮上忙,那就是CountDownTimer,利用它,我们可以很轻松地实现倒计时。很久以前我就用过这个类,但是这几天写时发现了一个当初没有注意到的坑,因此打算写一篇博客记录下来。

1、需求分析

  • 点击按钮之后,按钮文字变为“ns后发送验证码”(n为倒计时读数);
  • 为了让倒计时更加醒目,将秒数和单位设为蓝色;
  • 倒计时结束之后,按钮的文字显示为“重新发送”。

瞄一眼效果图:


2、工程创建和布局编写

创建工程就不用多说了,由于我们只需要看到按钮上的倒计时效果,不必输入手机号码,所以只要在界面上简单地放置一个按钮即可:



 

3、如何使用CountDownTimer

CountDownTimer倒计时器的使用并不难,我们可以创建一个类继承它,并实现它的构造函数和重写两个方法:

 private CountTimer countTimer;

 /**
  * 点击按钮后倒计时
  */
 class CountTimer extends CountDownTimer {

  public CountTimer(long millisInFuture, long countDownInterval) {
   super(millisInFuture, countDownInterval);
  }

  /**
   * 倒计时过程中调用
   *
   * @param millisUntilFinished
   */
  @Override
  public void onTick(long millisUntilFinished) {

  }

  /**
   * 倒计时完成后调用
   */
  @Override
  public void onFinish() {

  }
 }

大体的框架如上所述,我来稍微解释一下。首先是构造函数,里面有两个参数:

  • millisInFuture:倒计时的总时间,单位为毫秒
  • countDownInterval:倒计时的时间间隔,单位为毫秒

比如我想设置10秒的倒计时,每隔1秒就读一次数,那么初始化就可以将数值传入:

CountTimer countTimer = = new CountTimer(10000, 1000);

除了构造函数,还有两个方法,它们的作用分别如下:

  • onTick:倒计时过程中调用
  • onFinish:倒计时结束后调用

那么怎么开启倒计时呢?只需要用countTimer去调用start方法就可以了。另外,为了节省资源,在Activity销毁时应该停止倒计时:

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

到这里,你应该知道怎么使用如何使用CountDownTimer了吧?如果还有疑问,可以在文末下载完整的代码。

4、实现简单的倒计时效果

现在我们先来实现点击按钮后就进行倒计时读数的效果,代码如下:

 CountTimer countTimer = new CountTimer(10000, 1000);

 /**
  * 点击按钮后倒计时
  */
 class CountTimer extends CountDownTimer {

  public CountTimer(long millisInFuture, long countDownInterval) {
   super(millisInFuture, countDownInterval);
  }

  /**
   * 倒计时过程中调用
   *
   * @param millisUntilFinished
   */
  @Override
  public void onTick(long millisUntilFinished) {
   Log.e("Tag", "倒计时=" + (millisUntilFinished/1000));
   btnCaptcha.setText(millisUntilFinished / 1000 + "s后重新发送");
   //设置倒计时中的按钮外观
   btnCaptcha.setClickable(false);//倒计时过程中将按钮设置为不可点击
   btnCaptcha.setBackgroundColor(Color.parseColor("#c7c7c7"));
   btnCaptcha.setTextColor(ContextCompat.getColor(context, android.R.color.black));
   btnCaptcha.setTextSize(16);
  }

  /**
   * 倒计时完成后调用
   */
  @Override
  public void onFinish() {
   Log.e("Tag", "倒计时完成");
   //设置倒计时结束之后的按钮样式
   btnCaptcha.setBackgroundColor(ContextCompat.getColor(context, android.R.color.holo_blue_light));
   btnCaptcha.setTextColor(ContextCompat.getColor(context, android.R.color.white));
   btnCaptcha.setTextSize(18);
   btnCaptcha.setText("重新发送");
   btnCaptcha.setClickable(true);
  }
 }

倒计时的读数是实时的,毫无疑问应该在onTick方法中处理这些逻辑,倒计时完成后要将按钮文字改为“重新发送”,这个可以交给onFinish。

运行一下,点击按钮,倒计时成功出现了,但是再点几次,诡异的事情发生了:有时候倒计时读数会漏掉某个数字,比如从10直接就到8了,打印出来的日志是这样的:

这……到底是怎么回事?少掉的一秒难道是被某人给续了么?

5、CountDownTimer误差解决

为了找回生命中的这一秒钟,我在一个技术群里和小伙伴们讨论了很久,最后算是逃过了时间黑洞的魔爪。

我们采用的倒计时读数是将millisUntilFinished除于1000得到的,这里就有一个小小的陷阱了:millisUntilFinished是长整型变量,除于1000之后得到是整数部分。我们可以将millisUntilFinished的值打印出来看看:


现在明白为什么看不到读数9了吗?那是因为程序执行虽然很快,但再快也是需要时间的,所以从10秒倒计时到9秒时,millisUntilFinished会比9000稍小一点,是8999,而长整型8999除于1000之后就得到8了。当然,既然是误差那就有多种情况,少掉的数字不一定是9,这里只是我针对我遇到的情况而言。

知道原因之后就好办了,我们可以先将millisUntilFinished转换成double类型后再除于1000,这样就可以保留小数部分了,然后使用Math类中的round方法四舍五入,但是这样倒计时的话会从10到2,这显然不行,所以再减去1,让它从9到1。修改后的onTick方法代码是这样的:

  public void onTick(long millisUntilFinished) {
   //处理后的倒计时数值
   int time = (int) (Math.round((double) millisUntilFinished / 1000) - 1);
   btnCaptcha.setText(String.valueOf(time)+"s后重新发送");
   //设置倒计时中的按钮外观
   btnCaptcha.setClickable(false);//倒计时过程中将按钮设置为不可点击
   btnCaptcha.setBackgroundColor(Color.parseColor("#c7c7c7"));
   btnCaptcha.setTextColor(ContextCompat.getColor(context, android.R.color.black));
   btnCaptcha.setTextSize(16);
  }

运行后试试,就可以发现失去的那一秒又回来啦。

6、给倒计时读数和单位设置前景色

给同一字符串中的不同字符设置不同的字体颜色,这就需要用到SpannableString与SpannableStringBuilder相关的知识了,限于篇幅,这里就不赘述了,可以参考这篇文章:SpannableString与SpannableStringBuilder。这里只简单介绍一下:

6.1 拼接字符串

   int time = (int) (Math.round((double) millisUntilFinished / 1000) - 1);
   //拼接要显示的字符串
   SpannableStringBuilder sb = new SpannableStringBuilder();
   sb.append(String.valueOf(time));
   sb.append("s后重新发送");

6.2 设置要显示的文字样式

   //字符“后”在字符串中的下标
   int index = String.valueOf(sb).indexOf("后");
   //给秒数和单位设置蓝色前景色
   ForegroundColorSpan colorSpan = new ForegroundColorSpan(ContextCompat.getColor(context, android.R.color.holo_blue_dark));
   sb.setSpan(colorSpan, 0, index, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
   btnCaptcha.setText(sb);

这次运行之后就可以看到跟效果图一样的效果了。最后给一下源码:CountDownTimerDemo

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对的支持。


推荐阅读
  • 本文介绍了使用kotlin实现动画效果的方法,包括上下移动、放大缩小、旋转等功能。通过代码示例演示了如何使用ObjectAnimator和AnimatorSet来实现动画效果,并提供了实现抖动效果的代码。同时还介绍了如何使用translationY和translationX来实现上下和左右移动的效果。最后还提供了一个anim_small.xml文件的代码示例,可以用来实现放大缩小的效果。 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • 本文讨论了Alink回归预测的不完善问题,指出目前主要针对Python做案例,对其他语言支持不足。同时介绍了pom.xml文件的基本结构和使用方法,以及Maven的相关知识。最后,对Alink回归预测的未来发展提出了期待。 ... [详细]
  • 本文讲述了如何通过代码在Android中更改Recycler视图项的背景颜色。通过在onBindViewHolder方法中设置条件判断,可以实现根据条件改变背景颜色的效果。同时,还介绍了如何修改底部边框颜色以及提供了RecyclerView Fragment layout.xml和项目布局文件的示例代码。 ... [详细]
  • 在说Hibernate映射前,我们先来了解下对象关系映射ORM。ORM的实现思想就是将关系数据库中表的数据映射成对象,以对象的形式展现。这样开发人员就可以把对数据库的操作转化为对 ... [详细]
  • 本文介绍了在SpringBoot中集成thymeleaf前端模版的配置步骤,包括在application.properties配置文件中添加thymeleaf的配置信息,引入thymeleaf的jar包,以及创建PageController并添加index方法。 ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • Java验证码——kaptcha的使用配置及样式
    本文介绍了如何使用kaptcha库来实现Java验证码的配置和样式设置,包括pom.xml的依赖配置和web.xml中servlet的配置。 ... [详细]
  • Android系统移植与调试之如何修改Android设备状态条上音量加减键在横竖屏切换的时候的显示于隐藏
    本文介绍了如何修改Android设备状态条上音量加减键在横竖屏切换时的显示与隐藏。通过修改系统文件system_bar.xml实现了该功能,并分享了解决思路和经验。 ... [详细]
  • 本文介绍了Android 7的学习笔记总结,包括最新的移动架构视频、大厂安卓面试真题和项目实战源码讲义。同时还分享了开源的完整内容,并提醒读者在使用FileProvider适配时要注意不同模块的AndroidManfiest.xml中配置的xml文件名必须不同,否则会出现问题。 ... [详细]
  • Android开发实现的计时器功能示例
    本文分享了Android开发实现的计时器功能示例,包括效果图、布局和按钮的使用。通过使用Chronometer控件,可以实现计时器功能。该示例适用于Android平台,供开发者参考。 ... [详细]
  • Monkey《大话移动——Android与iOS应用测试指南》的预购信息发布啦!
    Monkey《大话移动——Android与iOS应用测试指南》的预购信息已经发布,可以在京东和当当网进行预购。感谢几位大牛给出的书评,并呼吁大家的支持。明天京东的链接也将发布。 ... [详细]
  • flowable工作流 流程变量_信也科技工作流平台的技术实践
    1背景随着公司业务发展及内部业务流程诉求的增长,目前信息化系统不能够很好满足期望,主要体现如下:目前OA流程引擎无法满足企业特定业务流程需求,且移动端体 ... [详细]
  • 本文介绍了在使用MSXML解析XML文件时出现DTD禁用问题的解决方案。通过代码示例和错误信息获取方法,解释了默认情况下DTD是禁用的,以及如何启用DTD的方法。此外,还提到了网上关于该问题的信息相对较少,因此本文提供了解决方案以供参考。 ... [详细]
  • 在Xamarin XAML语言中如何在页面级别构建ControlTemplate控件模板
    本文介绍了在Xamarin XAML语言中如何在页面级别构建ControlTemplate控件模板的方法和步骤,包括将ResourceDictionary添加到页面中以及在ResourceDictionary中实现模板的构建。通过本文的阅读,读者可以了解到在Xamarin XAML语言中构建控件模板的具体操作步骤和语法形式。 ... [详细]
author-avatar
赖军菁佳瑄柏昌
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有