当前位置: 首页 > news >正文

RecyclerView 倒计时和正计时方案

在这里插入图片描述

本章内容

  • 一.方案制定
  • 二.设计
  • 三.编码

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

一.方案制定

1.在Adapter中使用CountDownTimer
2.修改数据源更新数据
3.只修改页面展示的Item

第一种方案:如果使用CountDownTimer来进行倒计时的话,会造成计时器时间错乱的问题。计时器会根据你更新UI的次数越走越快。
第二种方案:在数据量不大的情况下,是可以进行使用的。但是会存在资源浪费,这里会将没有显示到页面中的数据也会进行运算操作。
第三种方案:第二种方案比第二种方案设计上会更加节省资源,并且不会伴随第一种方案的及时错乱。

二.设计

  • 创建RecyclerView.Adapter

  • 需要在ViewHodler里面添加一个计时器组件,使用Handler就足够满足需求。我们需要在进入屏幕时,开启倒计时,在滑出屏幕后,停止计时器来节省CPU资源。

  • 需要注意的是:进入屏幕会触发Recycler.Adapter的onBindViewHolder()函数,滑出屏幕会触发onViewRecycled()

    有以上准备,我们就可以进入撸码环节了。

三.编码

主要工作都在与RecyclerView.Holder中。

public class ChatItemHolder extends BaseViewHolder {
        //用来判断是倒计时还是正计时
        public boolean isCountdown;
        //这个是我的业务逻辑,触发正反计时就看是否反馈信息
        public boolean isFeedback;
		//倒计时/正计时时间
        public long delay;
        //倒计时任务
        private Runnable countdownRunnable = new Runnable() {
            @Override
            public void run() {
                delay -= 1000;
                if (delay == 0) {
                    isCountdown = false;
                } else {
                    isCountdown = true;
                }
                updateTimerState();
            }
        };
        //正计时任务
        private Runnable positiveTimeRunnable = new Runnable() {
            @Override
            public void run() {
                delay += 1000;
                updateTimerState();
            }
        };
        //启动倒计时
        public void startCountdown() {
            timerHandler.postDelayed(countdownRunnable, 1000);
        }
        //结束倒计时
        public void endCountDown() {
            timerHandler.removeCallbacks(countdownRunnable);
        }
        //启动正计时
        public void startPositiveTime() {
            timerHandler.postDelayed(positiveTimeRunnable, 1000);
        }
        //结束正计时
        public void endPositiveTime() {
            timerHandler.removeCallbacks(positiveTimeRunnable);
        }

        //更新UI
        public void updateTimerState() {
            if (isFeedback) {  //如果已反馈关闭计时器
                endCountDown();
                endPositiveTime();
            } else {//进行计时并显示的格式为1天1时1分1秒
                long time = delay / 1000; //变成秒
                long temp = time % (24 * 3600);
                long day = time / (24 * 3600); //天
                long hour = temp / 3600; //小时
                long minute = temp % 3600 / 60; //分钟
                long second = temp % 60; //秒
                if (isCountdown) {
                    if (day == 0) {
                        setText(R.id.command_feedback_state, "反馈剩余时间:" + hour + "时" + minute + "分" + second + "秒");
                    } else {
                        setText(R.id.command_feedback_state, "反馈剩余时间:" + day + "天" + hour + "时" + minute + "分" + second + "秒");
                    }
                    setTextColor(R.id.command_feedback_state, Color.parseColor("#1890ff"));
                    setBackgroundResource(R.id.command_feedback_state,
                            R.drawable.shape_solid_null_stroke_1890ff_corner);
                    startCountdown();
                } else {
                    if (day == 0) {
                        setText(R.id.command_feedback_state, "超时时间:" + hour + "时" + minute + "分" + second + "秒");
                    } else {
                        setText(R.id.command_feedback_state, "超时时间:" + day + "天" + hour + "时" + minute + "分" + second + "秒");
                    }
                    setTextColor(R.id.command_feedback_state, Color.parseColor("#ff001b"));
                    setBackgroundResource(R.id.command_feedback_state,
                            R.drawable.shape_solid_null_stroke_ff001b);
                    startPositiveTime();
                }
            }
        }


        public void display(CommandChatBean.Data.Records record) {
            long time = DateUtil.ifsUtcStringToLocalForLong(record.getCzsx());
            delay = time - System.currentTimeMillis();
            isCountdown = delay > 0;
            isFeedback = !TextUtils.isEmpty(record.getCcFksj());
            delay = Math.abs(delay);
            updateTimerState();
        }

        public void onRecycled() {
            endCountDown();
            endPositiveTime();
        }

        public ChatItemHolder(View view) {
            super(view);
        }
    }
    //recyclerView内写入的方法:该方法是为了关闭页面后可以移除所有计时任务
    public void recycleTime() {
        if (timerHandler != null) {
            timerHandler.removeCallbacksAndMessages(null);
            timerHandler = null;
        }
    }

我这里使用的是封装好的AdapterHelper,可以直接集成RecyclerView.ViewHolder进行获取控件在进行更新。替换我下面的代码逻辑:

  setText(R.id.command_feedback_state, "超时时间:" + hour + "时" + minute + "分" + second + "秒");
                    } else {
                        setText(R.id.command_feedback_state, "超时时间:" + day + "天" + hour + "时" + minute + "分" + second + "秒");
                    }
                    setTextColor(R.id.command_feedback_state, Color.parseColor("#ff001b"));
                    setBackgroundResource(R.id.command_feedback_state,
                            R.drawable.shape_solid_null_stroke_ff001b);

RecyclerAdapter的onBindViewHolder(ChatItemHolder viewHolder,int position)中使用方式:

···
if (!TextUtils.isEmpty(records.getCzsx()) && TextUtils.isEmpty(records.getCcFksj())) {
                baseViewHolder.setVisible(R.id.command_feedback_state, true);
                baseViewHolder.display(records);
            }
            if (TextUtils.isEmpty(records.getCzsx())) {
                baseViewHolder.setVisible(R.id.command_feedback_state, false);
            }
            if (!TextUtils.isEmpty(records.getCcFksj())) {
                baseViewHolder.setVisible(R.id.command_feedback_state, true);
                baseViewHolder.setText(R.id.command_feedback_state,
                        "已反馈:" + DateUtil.ifsUtcStringToLocalForString(records.getCcFksj()));
                baseViewHolder.setTextColor(R.id.command_feedback_state, Color.parseColor("#4BBA55"));
                baseViewHolder.setBackgroundResource(R.id.command_feedback_state,
                        R.drawable.shape_solid_null_stroke_4bba55);
            }
···            

今天就分享到这里了,祝小伙伴新年快乐!

相关文章:

  • 广州网站建设流程图/百度热度
  • java实现网站开发/无锡网站服务公司
  • 西安做百度网站公司/攀枝花网站seo
  • 做网站技术含量/义乌百度广告公司
  • 百度导航下载安装手机导航/seo视频教学网站
  • 长沙o2o网站制作公司/品牌seo主要做什么
  • 打工人必学的法律知识(五)——《女职工劳动保护特别规定》
  • Open3D 点云投影至指定球面(Python版本)
  • Elastic:使用 Postman 来访问
  • 制造企业数据/经营分析框架
  • 02【EB】- 独立于具体总线的底层通信堆栈模块概述
  • Spring 中最常用的 11 个扩展点
  • ESP-IDF:企业链表例程,实现初始化,插入,打印等功能。
  • 【pandas】17 数据处理和绘图
  • Redis缓存和数据库不一致性
  • k8s ingress概念和实践
  • 【论文速递】ECCV2022 - 开销聚合与四维卷积Swin Transformer_小样本分割
  • cmakelists例子