Android-RecyclerView列表倒计时错乱问题

Android中Recyclerview或ListView列表条目item中添加倒计时付款(解决时间错乱) 先看图: 在电商中一般都需要待付款倒计时功能,规定具体多少小时,到时间自动取消此订单,由于此倒计时是在列表中的每个item中都要显示,处理不好会出现倒计时错乱。 先看adapter中代码: public class MyWaitPayOrderAdapter extends RecyclerView.Adapter<MyWaitPayOrderAdapter.ViewHolder> ... 阅读详情

前言

转眼间距离上次写博客已是过了一个年轮,期间发生了不少事;经历了离职、找工作,新公司的第一版项目上线。现在总算是有时间可以将遇到的问题梳理下了,后期有时间也会分享更多的东西~~

场景

今天分享的问题是当在列表里面显示倒计时,这时候滑动列表会出现时间显示不正常的问题。首先关于倒计时我们需要注意的问题有以下几方面:

  1. 在RecyclerView中ViewHolder的复用导致的时间乱跳的问题。
  2. 滑动列表时倒计时会重置的问题。
  3. 在退出页面后定时器的资源释放问题,这里我使用的是用系统自带的CountDownTimer

ps:这里我们讨论的是对倒计时要求不是很严格的场景,对于用户手动修改系统时间这种操作没法预计;对于淘宝秒杀这种业务场景建议是实时不断请求后台拿取正确时间,对应的接口尽量设计简单,响应数据更快。

接下来通过代码具体了解:

代码

// 适配器
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
    //服务器返回数据
    private List<TimeBean> mDatas;
    //退出activity时关闭所有定时器,避免造成资源泄漏。
    private SparseArray<CountDownTimer> countDownMap;

    //记录每次刷新时的时间
    private long tempTime;

    public MyAdapter(Context context, List<TimeBean> datas) {
        mDatas = datas;
        countDownMap = new SparseArray<>();
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_common, parent, false);
        return new ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(final ViewHolder holder, int position) {
        final TimeBean data = mDatas.get(position);
        //记录时间点
        long timeStamp = System.currentTimeMillis() - tempTime;

        long time = data.getLeftTime() - timeStamp;

        //将前一个缓存清除
        if (holder.countDownTimer != null) {
            holder.countDownTimer.cancel();
        }
        if (time > 0) { //判断倒计时是否结束
            holder.countDownTimer = new CountDownTimer(time, 1000) {
                public void onTick(long millisUntilFinished) {
                    holder.timeTv.setText(getMinuteSecond(millisUntilFinished));
                }
                public void onFinish() {
                    //倒计时结束
                    holder.timeTv.setText("00:00");
                }
            }.start();

            countDownMap.put(holder.timeTv.hashCode(), holder.countDownTimer);
        } else {
            holder.timeTv.setText("00:00");
        }

    }

    @Override
    public int getItemCount() {
        if (mDatas != null && !mDatas.isEmpty()) {
            return mDatas.size();
        }
        return 0;
    }

    public class ViewHolder extends RecyclerView.ViewHolder {
        public TextView timeTv;
        public CountDownTimer countDownTimer;

        public ViewHolder(View itemView) {
            super(itemView);
            timeTv = (TextView) itemView.findViewById(R.id.tv_time);
        }
    }


    public void setGetTime(long tempTime) {
        this.tempTime = tempTime;
    }

    /**
     * 将毫秒数换算成 00:00 形式
     */
    public static String getMinuteSecond(long time) {
        int ss = 1000;
        int mi = ss * 60;
        int hh = mi * 60;
        int dd = hh * 24;

        long day = time / dd;
        long hour = (time - day * dd) / hh;
        long minute = (time - day * dd - hour * hh) / mi;
        long second = (time - day * dd - hour * hh - minute * mi) / ss;

        String strMinute = minute < 10 ? "0" + minute : "" + minute;
        String strSecond = second < 10 ? "0" + second : "" + second;
        return strMinute + ":" + strSecond;
    }

    /**
     * 清空资源
     */
    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();
            }
        }
    }
}

以上算是整个问题的核心代码了;其中SparseArray<CountDownTimer> 用来保存列表里面的定时器,用于退出页面时回收定时器。SparseArray是安卓特有的数据结构,建议多使用;data.getLeftTime() 是服务器返回的需要倒计时的时间,毫秒为单位。

问题一:ViewHolder的复用导致的数据错乱
if (holder.countDownTimer != null) {
       holder.countDownTimer.cancel();
   }

每次设置倒计时之前重置下倒计时即可解决。

问题二:滑动列表时倒计时会重置的问题

这个问题是由于解决问题一而导致的,因为列表滑动时离开屏幕的会被复用,这个时候我们会重新设置定时器,之前我是在倒计时里面记录倒计时剩余的时间然后重新设值,但是还是会有问题;这里借用了系统时间来解决,也就是tempTime 这个值。

首先在服务器请求成功后回调里面设置这个值,如:

    private MyAdapter adapter;

    @Override
    public void onHttpRequestSuccess(String url, HttpContext httpContext)      {
        if (服务器返回数据) {
            adapter.setGetTime(System.currentTimeMillis());
    }

相当于每次做刷新操作时获取的都是系统当时的时间戳。

然后在adapter里面计算

long timeStamp = System.currentTimeMillis() - tempTime;
long time = data.getLeftTime() - timeStamp;

其中tempTime就是我们保存的系统当前时间戳,然后每次滑动列表时都会调用onBindViewHolder,所以timeStamp就是记录的距离上次刷新经过了多少秒,然后用服务器返回的需要倒计时的时间减去经过的秒数就是还剩下的倒计时秒数。最后给定时器设置上就好了。

问题三:资源的释放

在当前的activity中调用以下方法。

@Override
protected void onDestroy() {
    super.onDestroy();
    if (adapter != null) {
        adapter.cancelAllTimers();
    }
}

好了,今天的分享就到这了,因为代码比较简单,布局都是一个Textview,所以没有贴出来,需要代码的可以留言~~

RecyclerView列表中的倒计时实现 一、概述 五一到了,劳动人民万岁!放假还要加班的程序员们,原本的回家或出行计划被迫放弃,他们辛苦了,希望老板们玩的开心。五一过完半年就差不多过去了,离十一也不远了。一年就这两个节点,过完这两个节点一年也到头了。 今天来说一下列表中倒计时的实现,这是我在实际项目用到的方案,不知道那些大厂是怎么实现的,他们一定有很好的方案。我这只是记录下我自己的实现,如果大家知道更好的实现,可以告诉我。 场景是有一个列表,比如购物车列表,item中会出现倒计时,比如秒杀倒计时。列表还支持分页,滑到第一页底部会加载下一页,下一页 阅读详情

相关推荐

Android RecyclerView滑动删除与撤销的工业级实现

滑动删除(Swipe-to-Delete)是移动应用中基础而关键的列表交互模式,其本质并非单纯UI动画,而是手势识别、视图渲染、数据同步与用户意图管理的系统性协调问题。底层依赖RecyclerView的复用机制与生命周期,需严格处理ACTION_CANCEL、ViewHolder复用污染、notifyItemRemoved异步时序等核心难点。ItemTouchHelper作为官方提供的嵌入式状态协调器,通过标准化方向判定、安全视图绘制(onChildDraw)、解耦的数据操作回调(onSwiped)及天然支

mybwu_com的专栏 398

RecyclerView倒计时解决方案

在开中难免遇到RecyclerView中带有倒计时的场景,有时候不止一个。那么如何实现一个带有倒计时的RecyclerView便是本文讨论的课题 1.在RecyclerView中实现高质量倒计时需要解决哪些问题。 当列表中有多个倒计时如何处理,开启多个还是统一管理?如果每个item都开启倒计时是否造成了资源浪费?不在展示区的倒计时又该如何取消?不在屏幕上的倒计时如何保证时间的准确性?只使用一个倒计时如何通知所有需要更新的item?如何保证不在屏幕上而不被通知的item的时间的准确性?能否在退出后台或者跳转

m0_56255097的博客 1305

解决Android-RecyclerView列表倒计时错乱问题

主要介绍了解决Android-RecyclerView列表倒计时错乱问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧

RecyclerView 倒计时和正计时方案

相信不少同学都会在这里栽跟头,在思考这个问题设计了两套方案,而我的项目需求中需要根据业务是否反馈来进行倒计时和正计时的操作。

不忘初心 1150

Android利用RecyclerView实现列表倒计时效果

主要为大家详细介绍了Android利用RecyclerView实现列表倒计时效果,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

Android实现倒计时效果

本文实例为大家分享了Android实现倒计时效果的具体代码,供大家参考,具体内容如下 一个倒计时的效果 先看效果图: 直接上代码: 这里是关于倒计时 …天时分秒…的逻辑判断 /** * 倒计时计算 */ private void computeTime() { mSecond--; if (mSecond < 0) { mMin--; mSecond = 59; if (mMin < 0) { mMin = 59; mHour--; if (mHour < 0) { // 倒计时结束 mHour = 23;

android列表倒计时,RecyclerView实现列表倒计时

最近在做一个项目,需要用到列表倒计时功能,捣鼓半天终于弄了出来,在安卓中实现这个效果需要用到Countdowntimer,通过这个类的使用,不仅可以实现倒计时的效果,还可以完美解决在实现倒计时过程中的两个bug。1.内存问题2.由于recyclerview的item复用导致不同条目的时间错乱首先看下实现的最终效果如何显示列表我相信大家都会,这里我只附上和倒计时功能实现的adapter类。publi...

weixin_34205814的博客 945

EtherCAT主站开发(学习笔记一)

摘要:本文介绍了基于STM32H7的EtherCAT主站开发探索。EtherCAT是一种高实时性工业以太网协议,具有低延迟、高带宽利用率等特点。文章详细解析了EtherCAT的协议架构、帧结构和工作原理,重点阐述了PDO数据传输过程及主从站通信机制。同时介绍了CoE、FoE等应用层协议扩展。作者将基于SOEM开源协议栈进行开发,为后续实际应用中的伺服电机控制奠定基础。

weixin_69388007的博客 1472

通过RecyclerView实现列表倒计时

最近在做一个项目,需要用到列表倒计时功能,捣鼓半天终于弄了出来,在安卓中实现这个效果需要用到Countdowntimer,这里讲此类进行分析并举例说明.

jcjkobe123的博客 6250

Ubuntu更新后VirtualBox报错rc=-1908?手把手教你修复Kernel driver not installed

本文详细解析了Ubuntu更新后VirtualBox报错rc=-1908的原因,并提供了完整的修复方案。通过重新安装VirtualBox、处理DKMS内核模块以及解决Secure Boot问题,帮助用户快速恢复虚拟机功能。特别针对Kernel driver not installed错误,给出了从诊断到修复的详细步骤。

weixin_42519781的博客 338

IBM System x3650 M5 IMM配置

1、IMM基本介绍 IMM,全称是Intel Mobile Module是IBM服务器上的集成管理模块,该模块是独立于服务器系统,可以通过一个单独的IP地址,使用Web和虚拟端口方式直接启动、停止和管理远程服务器,即使主板、处理器或者内存故障导致主机无法启动,也依然可以远程管理服务器,可以远程直接操作启动画面和服务器工作界面。 2、IP地址配置 2.1 通过Web方式修改IP地址 IBM服...

血饮渊虹的博客 4万+

Android 列表(ListView、RecyclerView)不断刷新最佳实践

本文微信公众号「AndroidTraveler」首发。 背景 在 Android 列表开发过程中,有时候我们的 Item 会有一些组件,比如倒计时。这类组件要求不断刷新,这个时候由于列表复用的机制,因此会有一些坑。那么我们本篇文章就给大家讲两个主题。 第一个是列表复用是否一定有问题。 第二个是出现问题有哪些解决方案可供我们选择。 小 Demo 由于我们的主题重点是为了解决不断刷新问题,因此关于 R...

高仿微信聊天界面长按弹框样式 751

WRF后处理避坑指南:从namelist配置到降水计算的全流程解析

本文提供了一份详尽的WRF模式后处理避坑指南,涵盖从理解wrfout文件结构、核心变量解析到累计降水计算与专业气象图绘制的全流程。重点解析了RAINC与RAINNC的正确处理方法,并分享了使用wrf-python库高效绘制位势高度叠加风场图、累计降水图等专业图表的实战技巧与代码,旨在帮助用户规避常见错误,提升后处理效率与图表质量。

weixin_29200485的博客 353

Android使用RecyclerView实现列表倒计时效果

最近接到个需求,需要将列表中的优惠券到期时间剩余两天时,设置倒计时效果,需求到手感觉应该问题不大。 实现倒计时方法主要有两个: 1、为每个开始倒计时的item设置一个定时器,再做更新item处理; 2、只启动一个定时器,然后遍历数据,再做更新item处理。 由于之前的倒计时功能已经封装使用了CountDownTimer类,所以我这边就选用第一种方法实现,直接就开干了,一波操作下来就实现了列表的倒计时效果,下图为模拟效果的demo,非正式项目,如图所示: 实现过程还是比较顺畅的,使用CountDownTim

开源世界 1137

完整IC设计流程解析&Makefile学习

本文介绍了decorder38项目的文件结构、自动化综合流程和Makefile使用方法。项目包含RTL到GDSII全流程文件,重点关注syn目录中的综合脚本。通过make dc命令运行综合流程,生成网表、约束和时序文件。关键报告如qor.rpt、area.rpt和min_vio.rpt用于分析综合质量、面积和时序。Makefile部分解释了其基本语法、IC设计中的典型结构,包括目标定义、命令执行和特殊声明,强调了其在自动化构建和依赖管理中的重要性。

m0_63352623的博客 855

CPU 访问外设的两种核心机制:MMIO(Memory-Mapped I/O) 和 DMA(Direct Memory Access)

BAR和DMA是计算机系统中两种关键的数据传输机制:BAR(基址寄存器)用于CPU与设备间的控制通信,映射设备寄存器便于配置操作;而DMA(直接内存访问)允许设备直接读写系统内存,无需CPU参与大量数据传输。典型场景如NVMe SSD读取数据时,CPU通过BAR下发指令,设备通过DMA高效传输数据到主机内存,最后中断通知CPU。虽然BAR能映射大内存空间,但仍无法替代DMA的高效数据传输功能,两者各司其职——BAR负责控制,DMA专注数据传输,共同实现高性能的硬件交互。

MHD0815的博客 237

android 倒计时 源码,Android RecyclerView实现拼团倒计时列表实例代码

Android RecyclerView实现拼团倒计时列表实例代码发布时间:2020-08-26 13:07:06来源:脚本之家阅读:319作者:黄二瓜前言最近一直被需求赶着走,有些功能经过测试上线后就没再review。闲下来还是重新优化下老代码,温故而知新,还是有点收获和进步的需求TODO团购这种促销方式已经很普遍,尤其是大家熟悉的“并夕夕”更是玩的很6。现在我们就要实现一个团购倒计时列表,并以...

weixin_39997795的博客 276

【YOLO11改进 - C3k2融合】C3k2融合AKConv(可改变核卷积)二次创新:任意数量的参数和任意采样形状的即插即用的卷积

【YOLO11改进 - C3k2融合】C3k2融合AKConv(可改变核卷积)二次创新:任意数量的参数和任意采样形状的即插即用的卷积

专注于图像领域,主要研究内容包括计算机视觉和深度学习,特别是在图像分类、目标检测和图像生成等方面有深入的研究和实践经验。 407

android 列表倒计时,RecyclerView实现拼团倒计时列表

最近一直被需求赶着走,有些功能经过测试上线后就没再review。闲下来还是重新优化下老代码,温故而知新,还是有点收获和进步的需求TODO团购这种促销方式已经很普遍,尤其是大家熟悉的“并夕夕”更是玩的很6。现在我们就要实现一个团购倒计时列表,并以“剩余:09:12:24.8”这种样式来展示该团距离结束时间的倒计时。技术初步分析首先,有关时间变化的,首先想到TimerTask+Timer这个定时器组合...

weixin_39567013的博客 244

YOLOv8与UNetV2融合:一种面向目标检测与图像分割的混合方法【附核心代码】

我们提出了一种基于YOLOv8和UNetV2相结合的混合架构。该架构利用YOLOv8作为主干进行目标检测,同时在YOLOv8的特征提取过程中,引入UNetV2来进行图像分割任务的增强。在该架构中,YOLOv8负责大范围目标检测和位置预测,而UNetV2则在检测网络的特征图基础上,通过其高效的上下文信息提取和细节恢复能力,进一步优化分割任务。在本文中,我们提出了一种改进YOLOv8的方法,通过引入图像分割网络UNetV2来提高图像分割检测性能。

一键难忘的博客 3524

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

recyclerView列表使用Timer定时器复用错乱的问题

相信许多小哥哥,小姐姐都遇到过recycleview列表复用错乱的问题,尤其是l列表中用到Timer定时器的时候,更容易出问题。 看下图:(只截取了列表的部分) 分析列表错乱的原因: 每一个item都有一个距开赛时间的倒计时(这个是用Timer自定义的),当item滑出界面的时候,timer 还在执行,没有停止,然后下个item复用了上个item的view, 但是注意了,t

qq_26665903的博客 5360

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

android recyclerview缓存_缓存问题解决办法

缓存导致的异常,本质是“缓存复用的ViewHolder状态”与“当前数据状态”不匹配。规范复用流程:在中全面重置状态,确保缓存的ViewHolder与新数据完全同步。优化缓存配置:合理定义viewType、调整缓存池容量、启用稳定 ID 等,提升缓存命中率。清理残留状态:通过或任务校验,避免异步操作干扰复用后的ViewHolder。理解这些策略不仅能解决具体问题,更能体现对缓存机制的深度掌握,在面试中也是加分项。

琦琦的博客 973

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

android listview 隐藏 刷新,Android 列表(ListView、RecyclerView)不断刷新最佳实践

本文微信公众号「AndroidTraveler」首发。背景在 Android 列表开发过程中,有时候我们的 Item 会有一些组件,比如倒计时。这类组件要求不断刷新,这个时候由于列表复用的机制,因此会有一些坑。那么我们本篇文章就给大家讲两个主题。第一个是列表复用是否一定有问题。第二个是出现问题有哪些解决方案可供我们选择。小 Demo由于我们的主题重点是为了解决不断刷新问题,因此关于 Recycle...

weixin_28810315的博客 319

android listview头部大图 刷新,Android 列表(ListView、RecyclerView)不断刷新最佳实践

本文微信公众号「AndroidTraveler」首发。背景在 Android 列表开发过程中,有时候我们的 Item 会有一些组件,比如倒计时。这类组件要求不断刷新,这个时候由于列表复用的机制,因此会有一些坑。那么我们本篇文章就给大家讲两个主题。第一个是列表复用是否一定有问题。第二个是出现问题有哪些解决方案可供我们选择。小 Demo由于我们的主题重点是为了解决不断刷新问题,因此关于 Recycle...

weixin_31847579的博客 327
上一篇: Glide-You cannot start a load for a destroyed activity
下一篇: 一个Android开发者眼中的微信小程序
Mackkill
博客等级 码龄15年 65粉丝 39原创
评论 12
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值