最近做倒计时领取红包功能,用到倒计时功能,由于不需要太精确,所以选择了系统提供的CountDownTimer实现倒计时功能。

1 CountDownTimer

CountDownTimer是Google提供的一个倒计时工具类,利用这个工具可以很方便的实现倒计时功能。

Schedule a countdown until a time in the future, with regular notifications on intervals along the way.
构造函数:
CountDownTimer(long millisInFuture, long countDownInterval)
参数说明:

  • millisInFuture :总倒计时时长
  • countDownInterval:每次时间间隔
    两个重要回调函数:
//countDownInterval间隔指定时间的回调,millisUntilFinished:剩余的时间
public abstract void onTick(long millisUntilFinished);
//倒计时结束时回调
public abstract void onFinish();

实现原理:CountDownTimer的源码很简单,内部利用Handler实现。

官方例子:

 new CountDownTimer(30000, 1000) {public void onTick(long millisUntilFinished) {System.out.println("===============seconds remaining: " + millisUntilFinished);}public void onFinish() {System.out.println("==============done!");}}.start();

**Result:
===============seconds remaining: 29969
===============seconds remaining: 28968
===============seconds remaining: 27967
===============seconds remaining: 26966
===============seconds remaining: 25965
===============seconds remaining: 24964
===============seconds remaining: 23962
===============seconds remaining: 22961
===============seconds remaining: 21959
===============seconds remaining: 20958
===============seconds remaining: 19957
===============seconds remaining: 18955
===============seconds remaining: 17954
===============seconds remaining: 16952
===============seconds remaining: 15951
===============seconds remaining: 14949
===============seconds remaining: 13948
===============seconds remaining: 12946
===============seconds remaining: 11945
===============seconds remaining: 10943
===============seconds remaining: 9942
===============seconds remaining: 8940
===============seconds remaining: 7939
===============seconds remaining: 6938
===============seconds remaining: 5937
===============seconds remaining: 4936
===============seconds remaining: 3935
===============seconds remaining: 2934
===============seconds remaining: 1934
==============done!

注意

**
可以看到每次onTrack中的时间都不是整秒数的值(不是30000,29000,28000,27000),而且误差越来越大。
存在问题:

  • 内部使用了Handler,同时倒计时一般和View绑定,所以当Activity或者Fragment销毁时一定要cancle掉
  • 每次 onTick() 返回的值都不是a*1000的整数,会有几毫秒的误差,由于最终我们会转成秒使用,就会造成倒计时时数值的跳跃。网上的解决方案是在总时间上添加一定误差时间达到准确的目的(10秒大概相差4-5毫秒)。
  • 最后执行onFinish明显感觉时间较长,一般接近两秒,且没有出现0值。

2 简单封装

public class CountDownTextView extends android.support.v7.widget.AppCompatTextView {private CountDownTimer mCountDownTimer;private long mCurrentTime = 0;private boolean isPause = false;private long mMaxTime = 60000;//当前倒计时时间private CurrentTimeListener mCurrentTimeListener;//倒计时完成之后的文案private String mFinishText = "完成";public String getmFinishText() {return mFinishText;}public void setmFinishText(String mFinishText) {this.mFinishText = mFinishText;}public CountDownTextView(Context context) {this(context, null, 0);}public CountDownTextView(Context context, AttributeSet attrs) {this(context, attrs, 0);}public CountDownTextView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);init();}public void setCurrentTimeListener( CurrentTimeListener tCurrentTimeListener){this.mCurrentTimeListener = tCurrentTimeListener;}public void setMaxTime(long time) {mMaxTime = time + 400;cancelCountDown();setText(getCountTimeByLong(mMaxTime));initCountDownTimer(mMaxTime);}private void init() {}public void initCountDownTimer(long millisInFuture) {mCountDownTimer = new CountDownTimer(millisInFuture, 1000) {@Overridepublic void onTick(long millisUntilFinished) {mCurrentTime = millisUntilFinished;if (mCurrentTimeListener != null){mCurrentTimeListener.currentTime(mCurrentTime);}setText(getCountTimeByLong(millisUntilFinished));isPause = false;}public void onFinish() {setText(mFinishText);}};}public void startCountDown() {if (mCountDownTimer != null && mMaxTime > 1000) {isPause = false;mCountDownTimer.start();}}public void cancelCountDown() {if (mCountDownTimer != null) {isPause = false;mCountDownTimer.cancel();}}public void resumeCountDown() {if (mCurrentTime != 0 && isPause) {initCountDownTimer(mCurrentTime);mCountDownTimer.start();isPause = false;}}public void pauseCountDown() {if (!isPause) {isPause = true;mCountDownTimer.cancel();}}public long getmCurrentTime() {return mCurrentTime;}public interface CurrentTimeListener{public void currentTime(long curTime);}public static String getCountTimeByLong(long finishTime) {int totalTime = (int) Math.round((double) finishTime / 1000);int hour = 0, minute = 0, second = 0;if (3600 <= totalTime) {hour = totalTime / 3600;totalTime = totalTime - 3600 * hour;}if (60 <= totalTime) {minute = totalTime / 60;totalTime = totalTime - 60 * minute;}if (0 <= totalTime) {second = totalTime;}StringBuilder sb = new StringBuilder();if (hour < 10) {sb.append("0").append(hour).append(":");} else {sb.append(hour).append(":");}if (minute < 10) {sb.append("0").append(minute).append(":");} else {sb.append(minute).append(":");}if (second < 10) {sb.append("0").append(second);} else {sb.append(second);}return sb.toString();}}

使用方式:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayoutxmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity174"><FrameLayoutandroid:layout_width="70dp"android:layout_height="wrap_content"><ImageViewandroid:layout_width="70dp"android:layout_height="50dp"android:scaleType="fitCenter"android:src="@mipmap/ic_launcher"/><com.ldx.canvasdrawdemo.CountDownTextViewandroid:id="@+id/countdown_text_view"android:layout_width="wrap_content"android:layout_height="wrap_content"android:background="@drawable/dialog_user_protocol_shape"android:layout_gravity="bottom|center_horizontal"android:gravity="center"android:paddingTop="1dp"android:paddingBottom="1dp"android:paddingLeft="2dp"android:paddingRight="2dp"app:layout_constraintTop_toTopOf="parent"app:layout_constraintLeft_toLeftOf="parent"app:layout_constraintRight_toRightOf="parent"/></FrameLayout></android.support.constraint.ConstraintLayout>
public class MainActivity174 extends AppCompatActivity {private CountDownTextView mCountDownTextView;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main174);SignedDialogFragment signedDialogFragment = SignedDialogFragment.newInstance(new SignedInfoResult(),true);signedDialogFragment.setCancelable(false);signedDialogFragment.show( getSupportFragmentManager(), SignedDialogFragment.TAG );mCountDownTextView = findViewById(R.id.countdown_text_view);mCountDownTextView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 9);mCountDownTextView.setMaxTime(300000);mCountDownTextView.setCurrentTimeListener(new CountDownTextView.CurrentTimeListener() {@Overridepublic void currentTime(long curTime) {//存储剩余时间}});mCountDownTextView.startCountDown();}//每次可见调用网络查看红包状态public void getRedPackState(){// 每次可见请求网络,如果失败不显示,如果成功进行下面判断// 1 如果状态显示已经完成则不显示,// 2如果没有完成,对比本地记录时间戳和返回时间戳,如果时间戳相同(没有完成),则本地记录的倒计时不变,开始倒计时,倒计时完成时更新状态//  如果时间戳不同(任务没有完成),则重新记录时间戳,然后初始化本地记录的时间,开始倒计时。}public void startCountDownText(long time){mCountDownTextView.setMaxTime(180000);mCountDownTextView.startCountDown();}
}

CountDownTimer 一步实现最简单的倒计时控件相关推荐

  1. android中倒计时控件CountDownTimer分析

    android中倒计时控件CountDownTimer分析1 示例代码 new CountDownTimer(10000, 1000) {public void onTick(long millisU ...

  2. Android之打造可定制的全场秒杀倒计时控件

    转载请标明出处: http://blog.csdn.net/hai_qing_xu_kong/article/details/51005062 本文出自:[顾林海的博客] ##前言 这几天翻看之前写的 ...

  3. android2.2 倒计时程序eclipse,Android倒计时控件

    8种机械键盘轴体对比 本人程序员,要买一个写代码的键盘,请问红轴和茶轴怎么选? Android倒计时控件,通常在发送验证码时用得最多.其实Android系统提供了一个倒计时控件叫做CountDownT ...

  4. android 倒计时 界面,Android倒计时控件实现

    原标题:Android倒计时控件实现 今日科技快讯 今年二季度小米手机出货2316万台,环比增长70%,预计明年小米手机的出货量将突破一亿台.而就在昨天,小米手机官微发布了招聘启事:"小米未 ...

  5. android 一分钟倒计时动画,Android利用属性动画自定义倒计时控件

    本文介绍一下利用属性动画(未使用Timer,通过动画执行次数控制倒计时)自定义一个圆形倒计时控件,比较简陋,仅做示例使用,如有需要,您可自行修改以满足您的需求.控件中所使用的素材及配色均是笔者随意选择 ...

  6. 如何在Android实现桌面清理内存简单Widget小控件

    如何在Android实现桌面清理内存简单Widget小控件 我们经常会看到类似于360.金山手机卫士一类的软件会带一个widget小控件,显示在桌面上,上面会显示现有内存大小,然后会带一个按键功能来一 ...

  7. 【WPF】一个简单的ColorPicker控件

    在斯克迪亚看到一篇WPF动态改变主题颜色的文章,来了兴趣,于是自己搞了个简单的ColorPicker控件. 控件其实很简单,定义了5个依赖属性 FinalBrushProperty, APropert ...

  8. 通过最简单的button控件,深入学习SAP UI5框架代码系列之零

    Jerry曾经作为SAP成都研究院的Fiori应用开发人员,从事了将近3年的SAP CRM Fiori应用开发,在使用SAP UI5的过程中,遇到过形形色色的问题,不少都是通过调试SAP UI5框架代 ...

  9. WPF 实现3D翻转倒计时控件~

    WPF开发者QQ群: 340500857       由于微信群人数太多入群请添加小编微信号  yanjinhuawechat 或 W_Feng_aiQ 邀请入群 需备注WPF开发者  PS:有更好的 ...

最新文章

  1. 北京大学万小军教授:让机器进行文学创作,有什么进展和挑战?
  2. php 补足字符串,php 数目字或者字符串补全
  3. 关注WebWork(四)
  4. js luhn算法_不会飞的鸟
  5. C语言sizeof和strlen的含义,用法和区别
  6. java 优先级文档_java 优先级队列.pdf
  7. micropython常用模块有那个_Python17个常用内置模块总结
  8. fullcalendar 只保留周_周末大利好!重磅全球指数加仓,210亿资金涌向A股「投资周历来了」...
  9. 计算机组成原理自考pdf,全国高等教育自学考试计算机组成原理.pdf
  10. VS2015安装VBpowerpacks工具箱教程
  11. 六安技师学院计算机网络技术,安徽六安技师学院2021年招生简章
  12. 软件测试常见面试题分享
  13. 2019CCPC湖南全国邀请赛(广东省赛、江苏省赛)重现赛
  14. Python操作FTP服务器实现文件和文件夹的上传与下载,python清理ftp目录下的所有文件和非空文件夹
  15. 《一本书读懂财报》学习笔记 - 资产是如何计价?
  16. Win10 Windows installer 服务
  17. Java之ByteBuffer详解
  18. 如何用php下载文件?
  19. npm install 你很明白吗
  20. 微信小程序订单语音播报

热门文章

  1. Requests库常用方法及参数介绍
  2. AWVS扫描web站点
  3. 遇到程序员不修改bug时怎么办?我教你
  4. 【数据库SQL实战】获取员工其当前的薪水比其manager当前薪水还高的相关信息
  5. linux开源项目github,GitHub 上的优质 Linux 开源项目,真滴牛逼!
  6. 服务器本地视频怎么网站播放视频教程,远程服务器的视频怎么在本地播放
  7. 洛谷P3224【HNOI2012】永无乡
  8. usb接口供电不足_win7笔记本USB接口不够用的解决教程
  9. 车站安防巡逻机器人未来发展趋势是什么?
  10. Excel中IF函数的使用