Android倒计时功能的简单实现和改进

项目中经常会遇到找回密码的功能,现在找回密码一般都是用手机接收验证码,为了防止多次发送,一般需要设置一个发送间隔,比如60秒。为了让用户更加清楚的感受到这个间隔,于是就出现了倒计时功能.如下图:

点击之后,获取验证码的那个TextView或者Button变为不可点击,并且它的的text就要每秒变化一次,59,58,57…到最后一秒之后,text重新变为点击获取验证码,而且变为可点击.

看了一些前辈写的倒计时,都是用Handler和TimerTask来实现,然后我发现了一个更加简单的,Android自带的类来写这个功能.

接下来我就以一个简单的例子来实现这个功能。

1、activity_main.XML,为一个Button即可.

<RelativeLayout xmlns:android=”http://schemas.android.com/apk/res/android”

xmlns:tools=”http://schemas.android.com/tools”
android:layout_width=”match_parent”
android:layout_height=”match_parent”
>

<Button
android:textSize=”25dp”
android:id=”@+id/btn_get”
android:layout_width=”fill_parent”
android:layout_height=”fill_parent”
android:text=”点击获取验证码” />

</RelativeLayout>

2、MainActivity.java,既为重头戏,又极为简单.

package com.example.rr;

import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class MainActivity extends Activity {

private Button mButton;//定义一个Button
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mButton=(Button) findViewById(R.id.btn_get);//←←获取按钮ID
//设置监听↓↓
mButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
mButton.setClickable(false);
mButton.setTextColor(Color.parseColor(“#FF0000″));
MyTimer myTimer=new MyTimer(5000, 1000);//定义MyTimer的对象
myTimer.start();//启动倒计时
}});

}
private class MyTimer extends CountDownTimer{

//millisInFuture为你设置的此次倒计时的总时长,比如60秒就设置为60000
//countDownInterval为你设置的时间间隔,比如一般为1秒,根据需要自定义。
public MyTimer(long millisInFuture, long countDownInterval) {
super(millisInFuture, countDownInterval);
// TODO Auto-generated constructor stub

}@Override
public void onTick(long millisUntilFinished) {
// TODO Auto-generated method stub
mButton.setText(millisUntilFinished/1000+”秒后重新获取”);
}
//每过你规定的时间间隔做的操作↑↑
//倒计时结束时做的操作↓↓
@Override
public void onFinish() {
// TODO Auto-generated method stub
mButton.setClickable(true);
mButton.setTextColor(Color.parseColor(“#000000”));
mButton.setText(“点击获取验证码”);
}}}

在各个关键点我也做了标注,下面是我给大家录的gif.

timer

大家可以发现有2个问题:

1、在1秒的时候,会停顿大约两秒,这样就给了用户不太好的体验,还以为是手机卡了.为什么会出现这种问题呢?

2、点击Button时,出现的是数字4而不是数字5。

首先我们得知道这种方法的原理是什么,大家先看一下CountDownTimer的源码:

首先大家看一下这句: mStopTimeInFuture = SystemClock.elapsedRealtime() + mMillisInFuture;

再看下下面的这句:  final long millisLeft = mStopTimeInFuture – SystemClock.elapsedRealtime();

(注意:SystemClock.elapsedRealtime()返回的是系统运行到现在的时间,每时每刻都在变化);

如果简单的进行数学计算的话,那么一开始mStopTimeInFuture是等于millisLeft的,但是不然,SystemClock.elapsedRealtime()返回的时间,以毫秒为单位,也就是说,从上面运行到下面,也消耗了些许时间,那么millisLeft就是小于5000的。

回到我们的Activity,我们在内部类的OnTick里写了什么?

mButton.setText(millisUntilFinished/1000+”秒后重新获取”);那么4900多除以1000后,返回的数值为4。

 解决方案:

                   在我们实例化MyTimer时,将5000改为6000.

 至于在1秒处停顿的情况,我们看一下最下面的if else 语句:

if (millisLeft <= 0) {
onFinish();
} else if (millisLeft < mCountdownInterval) {
// no tick, just delay until done
sendMessageDelayed(obtainMessage(MSG), millisLeft);
} else {
long lastTickStart = SystemClock.elapsedRealtime();
onTick(millisLeft);

在 else if 语句处,当millisLeft<mCountdownInterval=1000,时,只进行停顿,而不调用OnTick方法,也就是说,我们运行程序时,millisLeft的数值从4900多~3900~2900~1900~900,900的时候,运行到这里,就会停顿,而不显示我们在OnTick写的代码.

           解决方案:

       重写CountDownTimer类。 

      然后, 

     1、在else if 中加OnTick(millisLeft);

2、删掉这个if  else 语句

    OK,我在重写类之后,将if else 语句改为下面的时候,依旧可以完成倒计时功能:

 if (millisLeft <= 0) {
onFinish();
} else {
onTick(millisLeft);
sendMessageDelayed(obtainMessage(MSG), 1000);
}

效果gif如下:

是不是写这个类的大牛想复杂了,还是我这个方法有问题呢?有知道的道友可以联系我~万分感谢!

PS:写这个文章浪费了快一下午,原因是网速不好,快写完了,保存草稿,然后出现意外,导致没保存,所以,,,,但是还是希望得到各位的建议和鼓励,谢谢!

时间: 2025-01-25 00:45:24

Android倒计时功能的简单实现和改进的相关文章

android 照相功能的简单实例

在android中,照相功能系统已经提供,在app中可以直接使用.当手机从android play里面下载有照相功能的应用时, 会判断手机是否支持.不支持,不给予下载.照相有几个步骤:1. 声明权限2. 使用Camera照相3. 显示图片 1. 声明权限在manifest里面声明使用Camera:复制代码 代码如下:<uses-feature android:name="android.hardware.camera" /> 2. 使用Camera照相 在Activity中

android实现倒计时功能的方法_Android

前言   在打开爱奇艺等app的欢迎界面的时候,右上角有一个倒计时的控件.倒计时完了以后进入主界面.现在我们来实现这个功能.  方法一: 利用java的类Timer,TimerTask还有android的Handler 界面welcome_activity.xml  <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.an

Android自定义Chronometer实现短信验证码秒表倒计时功能_Android

本文实例为大家分享了Chronometer实现倒计时功能,Android提供了实现按照秒计时的API,供大家参考,具体内容如下 一.自定义ChronometerView 继续自TextView 主要原理:先设置一个基准倒计时时间mBaseSeconds,内置handler 每隔1s发送一个空消息,mRemainSeconds--,同时刷新界面视图,回调给外部调用者,只到为零.外部调用者可通过start()/pause()/stop()来控制计时器的工作状态. 可以app中发送短信验证码的场景为例

Android利用Chronometer实现倒计时功能_Android

项目需要实现一个计时的功能,利用Chronometer虽然可以很方便的实现计时功能,但需要的却是一个倒计时控件. 百度了一下方法不少,倒计时的却没有,于是用Chronometer封装了一个倒计时的类,本着开源的精神,分享给大家! 废话不说了,进入主题 首先xml布局如下: <com.example.anticlockwisedemo.Anticlockwise android:id="@+id/id_timer" android:layout_width="wrap_c

Android基于CountDownTimer实现倒计时功能_Android

本文实例讲述了Android编程基于CountDownTimer实现倒计时功能的方法.分享给大家供大家参考,具体如下: 在逛论坛的时候,看到一个网友提问,说到了CountDownTimer这个类,从名字上面大家就可以看出来,记录下载时间.将后台线程的创建和Handler队列封装成一个方便的类调用. 查看了一下官方文档,这个类及其简单,只有四个方法,上面都涉及到了onTick,onFinsh.cancel和start.其中前面两个是抽象方法,所以要重写一下. 下面是官方给的一个小例子: new C

Android中CountDownTimer 实现倒计时功能

CountDownTimer CountDownTimer 是android 自带的一个倒计时类,使用这个类可以很简单的实现 倒计时功能 CountDownTimer 的实现方式 new CountDownTimer(6000,1000) {//第一个参数表示的是倒计时的总时间,第二参数表示的是倒计时的间隔时间. @Override public void onTick(long millisUntilFinished) {//倒计时的过程 textView.setText(millisUnti

jQuery基于扩展简单实现倒计时功能的方法_jquery

本文实例讲述了jQuery基于扩展简单实现倒计时功能的方法.分享给大家供大家参考,具体如下: jQuery.fn.countDown = function(settings,to) { settings = jQuery.extend({ startFontSize: '36px', endFontSize: '12px', duration: 1000, startNumber: 10, endNumber: 0, callBack: function() { } }, settings);

自己封装的一个简单的倒计时功能实例_javascript技巧

因为平常工作中很常用到该功能,所以就利用这次国庆假期,重新梳理与对原有代码进行改善,再集成一个常用的功能,最终封装出这个"简单倒计时"功能. 该倒计时方法具有以下该功能: 1. 根据指定日期与当前的电脑时间进行匹配 2. 通过指定一个数组参数,来设置在每一天内不同的时间段进行倒计时. * 该方法还未通过实际工作的检测,稳定性未知(如果实际工作通过,会删除这段话) function countDown(date,target,filter){ var setTime = new Date

jQuery实现简单倒计时功能的方法_jquery

本文实例讲述了jQuery实现简单倒计时功能的方法.分享给大家供大家参考,具体如下: 1.效果图如下: 2.html代码: <div class="timeFix"> <div class="daojishi" id="09/04/2016 00:00:00"> <span class="timeh"></span> <span class="timem"