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);
            }
···            

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

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
RecyclerView中设置计时器可以通过以下步骤实现: 1. 在RecyclerView的Adapter中,创建一个计时器对象,并在每个ViewHolder中启动计时器。可以在ViewHolder的构造函数中创建计时器对象,并在onBindViewHolder方法中启动计时器。 2. 在ViewHolder中,实现计时器的逻辑。可以使用CountDownTimer类来实现倒计时功能。在onTick方法中更新ViewHolder中的计时器显示,并在onFinish方法中处理计时器结束的逻辑。 3. 在RecyclerView的Adapter中,处理RecyclerView的滚动事件。当RecyclerView滚动时,可以通过监听RecyclerView的滚动事件来暂停或重新启动计时器。可以在RecyclerView的addOnScrollListener方法中添加一个滚动监听器,并在滚动监听器中处理计时器的暂停和重新启动逻辑。 通过以上步骤,你可以在RecyclerView的每个单元格中设置计时器,并在滚动时确地管理计时器的状态,避免闪烁和混乱的问题。 #### 引用[.reference_title] - *1* *2* [RecyclerView 倒计时计时方案](https://blog.csdn.net/xiaohai695943820/article/details/128700380)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [android – 带有多个倒计时器的Recyclerview会导致闪烁](https://blog.csdn.net/weixin_28749997/article/details/117500621)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值