android列表倒计时,RecyclerView实现列表倒计时
最近在做一个项目,需要用到列表倒计时功能,捣鼓半天终于弄了出来,在安卓中实现这个效果需要用到Countdowntimer,通过这个类的使用,不仅可以实现倒计时的效果,还可以完美解决在实现倒计时过程中的两个bug。
1.内存问题
2.由于recyclerview的item复用导致不同条目的时间错乱
首先看下实现的最终效果
如何显示列表我相信大家都会,这里我只附上和倒计时功能实现的adapter类。
public class ClockAdapter extends RecyclerView.Adapter {
private SparseArray countDownMap = new SparseArray<>();
@Override
public ClockViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_rv, parent, false);
return new ClockViewHolder(view);
}
/**
* 清空资源
*/
public void cancelAllTimers() {
if (countDownMap == null) {
return;
}
for (int i = 0,length = countDownMap.size(); i < length; i++) {
CountDownTimer cdt = countDownMap.get(countDownMap.keyAt(i));
if (cdt != null) {
cdt.cancel();
}
}
}
@Override
public void onBindViewHolder(final ClockViewHolder holder, int position) {
long betweenDate;
if (position == 0) {
betweenDate= DateUtil.getLeftTime("2017-8-8 12:10:10");
} else {
betweenDate= DateUtil.getLeftTime("2017-8-9 15:10:10");
}
if (holder.countDownTimer != null) {
holder.countDownTimer.cancel();
}
if (betweenDate > 0) {
holder.countDownTimer = new CountDownTimer(betweenDate, 1000) {
public void onTick(long millisUntilFinished) {
millisUntilFinished = millisUntilFinished / 1000;
int hours = (int) (millisUntilFinished / (60 * 60));
int leftSeconds = (int) (millisUntilFinished % (60 * 60));
int minutes = leftSeconds / 60;
int seconds = leftSeconds % 60;
final StringBuffer sBuffer = new StringBuffer();
sBuffer.append(addZeroPrefix(hours));
sBuffer.append(":");
sBuffer.append(addZeroPrefix(minutes));
sBuffer.append(":");
sBuffer.append(addZeroPrefix(seconds));
holder.clock.setText(sBuffer.toString());
}
public void onFinish() {
// 时间结束后进行相应逻辑处理
}
}.start();
countDownMap.put(holder.clock.hashCode(), holder.countDownTimer);
} else {
// 时间结束 进行相应逻辑处理
}
}
@Override
public int getItemCount() {
return 25;
}
class ClockViewHolder extends RecyclerView.ViewHolder {
TextView clock;
CountDownTimer countDownTimer;
public ClockViewHolder(View itemView) {
super(itemView);
clock = (TextView) itemView.findViewById(R.id.clock);
}
}
}
其中cancelAllTimer()这个方法解决了内存的问题,通过这行代码,将item的hashcode作为key设入SparseArray中,这样在cancelAllTimer方法中可以一个一个取出来进行倒计时取消操作。
countDownMap.put(holder.clock.hashCode(),holder.countDownTimer);
接着通过下面这行代码新建一个CountDownTimer类
holder.countDownTimer = new CountDownTimer(betweenDate, 1000) {
public void onTick(long millisUntilFinished) {
millisUntilFinished = millisUntilFinished / 1000;
int hours = (int) (millisUntilFinished / (60 * 60));
int leftSeconds = (int) (millisUntilFinished % (60 * 60));
int minutes = leftSeconds / 60;
int seconds = leftSeconds % 60;
final StringBuffer sBuffer = new StringBuffer();
sBuffer.append(addZeroPrefix(hours));
sBuffer.append(":") sBuffer.append(addZeroPrefix(minutes));
sBuffer.append(":");
sBuffer.append(addZeroPrefix(seconds));
holder.clock.setText(sBuffer.toString());
}
public void onFinish() {
// 时间结束后进行相应逻辑处理
}
}.start();
分析它的源码
public CountDownTimer(long millisInFuture, long countDownInterval) {
mMillisInFuture = millisInFuture;
mCountdownInterval = countDownInterval;
}
从中可以很清楚的看出,设置了两个值,第一个是倒计时结束时间,第二个是刷新时间的间隔时间。
然后通过start方法进行启动,接着看下start方法中进行的处理
public synchronized final CountDownTimer start() {
mCancelled = false;
if (mMillisInFuture <= 0) {
onFinish();
return this;
}
mStopTimeInFuture = SystemClock.elapsedRealtime() + mMillisInFuture;
mHandler.sendMessage(mHandler.obtainMessage(MSG));
return this;
}
源码中,当倒计时截止时间小于等0时也就是倒计时结束时,调用了onFinish方法,若时间还未结束,则通过handler的异步消息机制,将消息进行发出,通过一整个流程,最终方法会走到handler的handleMessage方法中,如果有不熟悉这个异步流程的伙伴,可以去看我以前写的一篇异步消息机制的文章 android异步消息机制,源码层面彻底解析。好了,接下来就来看看handler的handleMessage方法。
private Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
synchronized (CountDownTimer.this) {
if (mCancelled) {
return;
}
final long millisLeft = mStopTimeInFuture - SystemClock.elapsedRealtime();
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);
// take into account user's onTick taking time to execute
long delay = lastTickStart + mCountdownInterval - SystemClock.elapsedRealtime();
// special case: user's onTick took more than interval to
// complete, skip to next interval
while (delay < 0) delay += mCountdownInterval;
sendMessageDelayed(obtainMessage(MSG), delay);
}
}
}
};
相信这段源码还是很通熟易懂,首先计算出剩余时间,如果剩余时间小于刷新时间,就发送一条延时消息直到时间结束,如果剩余时间大于刷新时间就调用onTick(millisLeft)方法,这个方法在我们创建CountDownTimer类时就进行过重写,在里面就可以写我们倒计时展示的具体逻辑了。至此整个流程结束。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。
android列表倒计时,RecyclerView实现列表倒计时相关推荐
- android开发 RecyclerView 瀑布列表布局
android开发 RecyclerView 瀑布列表布局 1.写一个内容的自定义小布局: <?xml version="1.0" encoding="utf-8& ...
- android开发实现选择列表,Android使用RecyclerView实现列表数据选择操作
Android使用RecyclerView实现列表数据选择操作 发布时间:2020-08-31 17:50:13 来源:脚本之家 阅读:76 作者:迟做总比不做强 这些时间做安卓盒子项目,因为安卓电视 ...
- android之网络请求 -- 获取RecyclerView的列表项(图片 + 文字)
android之网络请求 -- 获取RecyclerView的列表项 示意图,网络请求的地址,插件及依赖 代码架构 代码内容 MainActivity.java activity_main.xml R ...
- Android实战开发-Kotlin教程(入门篇-RecyclerView数据列表的实现)
在移动应用开发中,很多时候我们需要去展示数据记录,如电商应用中的商品列表.订单列表等等一系列的数据记录的展示时,我们需要用到Android的列表组件展示这些数据,列表组件应该是我们遇到到比较常见也是必 ...
- 带倒计时RecyclerView的设计心路历程
/ 今日科技快讯 / 伴随着联想集团终止科创板IPO,在高负债率下已退休的柳传志约1亿元的高薪酬也被外界所质疑.此前有消息称,柳传志在香港上市公司联想集团拿317万美元的年薪,其在2020年的 ...
- 微信读书android换到ios,Android 微信读书本周推荐传送带列表实现
实现效果 image 使用 android:id="@+id/carousel" android:layout_width="match_parent" and ...
- Android商城开发----点击左侧分类列表右侧更新对应列表内容
Android商城开发----点击左侧分类列表右侧更新对应列表内容 目录 Android商城开发----点击左侧分类列表右侧更新对应列表内容 一.首先说布局: 二.主要说一下,布局完成后实现点击左侧类 ...
- Android 顶部标签栏及内容列表的设计与实现
文章目录 一.使用ViewPager控件实现翻页效果 案例演示 1.主页面添加ViewPager控件 2.创建适配器继承FragmentPagerAdapter 3.为ViewPager对象设置适配器 ...
- Android学习系列(10)--App列表之拖拽ListView(上)
研究了很久的拖拽ListView的实现,受益良多,特此与尔共飨. 鉴于这部分内容网上的资料少而简陋,而具体的实现过程或许对大家才有帮助,为了详尽而不失真,我们一步一步分析,分成两篇文章. ...
最新文章
- oracle审计功能ip地址,oracle 11g 审计功能
- [shiro学习笔记]第二节 shiro与web融合实现一个简单的授权认证
- 『飞秋』在ASP.NET服务器端过程中使用WebBrowser的注意事项
- dos打开计算机管理,小何 发布 DOS 命令打开控制面板各项东东 你们懂得...
- 68 个人脸landmark 点分布图
- HTML之表格的基本知识
- 【转载】Linux等类Unix系统学习用书那点事儿!
- mqtt 推送的客户端测试方法
- 图像坐标球面投影_从球面到平面的投影
- 【快递100】 物流公司对应编码分享(截止到2021-09-19 最新数据)
- PyCharm2017破解步骤
- 在Python中用WordCloud生成聊天记录热点词汇词云图
- Android9.0 短信发送和彩信接受流程
- alios things开发板_AliOS Things图形界面开发指南
- 公司发给你一个gitLab账号怎么配置项目!
- 小程序--时间处理(显示几分钟前,,几小时前,,几天前...)
- 好用的免费代理池搭建
- 评价类问题解决方法及模型汇总
- 南开大学张昊计算机,张昊(东北大学工商管理学院副教授)_百度百科
- Ubuntu下利用安装包手动安装Apache和Php
热门文章
- 3D模型欣赏:白发小恶魔女 次世代角色设计 毛发细腻
- 《JavaScript交互式网页设计》复习考试
- 西门子300 PLC 功能块及背景数据块的说明
- github账户登录ArcGIS developer并申请API key
- php取网盘真实链接,利用蓝奏做个人小文件网盘和获取真实下载地址
- unix系统病毒概述(转)
- 原型软件--Balsamiq Mockups
- win7局域网计算机 慢,Win7系统局域网访问文件速度缓慢怎么办
- 基于SSD的CCTSDB交通标识数据集目标检测
- 计算机毕业设计django基于python学生考试成绩数据分析与可视化系统(源码+系统+mysql数据库+Lw文档)