CountDownTimer 一步实现最简单的倒计时控件
最近做倒计时领取红包功能,用到倒计时功能,由于不需要太精确,所以选择了系统提供的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 一步实现最简单的倒计时控件相关推荐
- android中倒计时控件CountDownTimer分析
android中倒计时控件CountDownTimer分析1 示例代码 new CountDownTimer(10000, 1000) {public void onTick(long millisU ...
- Android之打造可定制的全场秒杀倒计时控件
转载请标明出处: http://blog.csdn.net/hai_qing_xu_kong/article/details/51005062 本文出自:[顾林海的博客] ##前言 这几天翻看之前写的 ...
- android2.2 倒计时程序eclipse,Android倒计时控件
8种机械键盘轴体对比 本人程序员,要买一个写代码的键盘,请问红轴和茶轴怎么选? Android倒计时控件,通常在发送验证码时用得最多.其实Android系统提供了一个倒计时控件叫做CountDownT ...
- android 倒计时 界面,Android倒计时控件实现
原标题:Android倒计时控件实现 今日科技快讯 今年二季度小米手机出货2316万台,环比增长70%,预计明年小米手机的出货量将突破一亿台.而就在昨天,小米手机官微发布了招聘启事:"小米未 ...
- android 一分钟倒计时动画,Android利用属性动画自定义倒计时控件
本文介绍一下利用属性动画(未使用Timer,通过动画执行次数控制倒计时)自定义一个圆形倒计时控件,比较简陋,仅做示例使用,如有需要,您可自行修改以满足您的需求.控件中所使用的素材及配色均是笔者随意选择 ...
- 如何在Android实现桌面清理内存简单Widget小控件
如何在Android实现桌面清理内存简单Widget小控件 我们经常会看到类似于360.金山手机卫士一类的软件会带一个widget小控件,显示在桌面上,上面会显示现有内存大小,然后会带一个按键功能来一 ...
- 【WPF】一个简单的ColorPicker控件
在斯克迪亚看到一篇WPF动态改变主题颜色的文章,来了兴趣,于是自己搞了个简单的ColorPicker控件. 控件其实很简单,定义了5个依赖属性 FinalBrushProperty, APropert ...
- 通过最简单的button控件,深入学习SAP UI5框架代码系列之零
Jerry曾经作为SAP成都研究院的Fiori应用开发人员,从事了将近3年的SAP CRM Fiori应用开发,在使用SAP UI5的过程中,遇到过形形色色的问题,不少都是通过调试SAP UI5框架代 ...
- WPF 实现3D翻转倒计时控件~
WPF开发者QQ群: 340500857 由于微信群人数太多入群请添加小编微信号 yanjinhuawechat 或 W_Feng_aiQ 邀请入群 需备注WPF开发者 PS:有更好的 ...
最新文章
- 北京大学万小军教授:让机器进行文学创作,有什么进展和挑战?
- php 补足字符串,php 数目字或者字符串补全
- 关注WebWork(四)
- js luhn算法_不会飞的鸟
- C语言sizeof和strlen的含义,用法和区别
- java 优先级文档_java 优先级队列.pdf
- micropython常用模块有那个_Python17个常用内置模块总结
- fullcalendar 只保留周_周末大利好!重磅全球指数加仓,210亿资金涌向A股「投资周历来了」...
- 计算机组成原理自考pdf,全国高等教育自学考试计算机组成原理.pdf
- VS2015安装VBpowerpacks工具箱教程
- 六安技师学院计算机网络技术,安徽六安技师学院2021年招生简章
- 软件测试常见面试题分享
- 2019CCPC湖南全国邀请赛(广东省赛、江苏省赛)重现赛
- Python操作FTP服务器实现文件和文件夹的上传与下载,python清理ftp目录下的所有文件和非空文件夹
- 《一本书读懂财报》学习笔记 - 资产是如何计价?
- Win10 Windows installer 服务
- Java之ByteBuffer详解
- 如何用php下载文件?
- npm install 你很明白吗
- 微信小程序订单语音播报