设为首页 加入收藏

TOP

Android利用RecyclerView实现列表倒计时效果(一)
2019-09-01 23:13:46 】 浏览:89
Tags:Android 利用 RecyclerView 实现 倒计时 效果

最近面试时,面试官问了一个列表倒计时效果如何实现,然后脑袋突然懵的了O(∩_∩)O,现在记录一下。

运行效果图

Alt

实现思路

实现方法主要有两个:
1.为每个开始倒计时的item启动一个定时器,再做更新item处理;
2.只启动一个定时器,然后遍历数据,再做再做更新item处理。
经过思考,包括性能、实现等方面,决定使用第2种方式实现。

实现过程

  • 数据实体
/** 
  * 总共的倒计时的时间(结束时间-开始时间),单位:毫秒 
  * 例: 2019-02-23 11:00:30 与 2019-02-23 11:00:00 之间的相差的毫秒数 
  */  
 private long totalTime;  
 /** 
  * 倒计时是否在暂停状态 
  */  
 private boolean isPause = true;  
  • 倒计时
    Timer
mTimer.schedule(mTask, 0, 1000);

TimerTask

 class MyTask extends TimerTask {
        @Override
        public void run() {
            if (mList.isEmpty()) {
                return;
            }
            int size = mList.size();
            CountDownTimerBean bean;
            long totalTime;
            for (int i = 0; i < size; i++) {
                bean = mList.get(i);
                if (!bean.isPause()) {//不处于暂停状态
                    totalTime = bean.getTotalTime() - 1000;
                    if (totalTime <= 0) {
                        bean.setPause(true);
                        bean.setTotalTime(0);
                    }
                    bean.setTotalTime(totalTime);
                    Message message = mHandler.obtainMessage(1);
                    message.arg1 = i;
                    mHandler.sendMessage(message);
                }
            }
        }
    }
  • 线程交互更新item
 mHandler = new Handler(Looper.getMainLooper()) {
            @Override
            public void handleMessage(Message msg) {
                switch (msg.what) {
                    case 1:
                        notifyItemChanged(msg.arg1, "update-time");
                        break;
                }
            }
        };
  • 性能优化方面
    1.调用notifyItemChanged()方法后,不要更新整个item(比如说item包含图片,不需要变的),所以要重写onBindViewHolder( Holder , int , List )方法:
    @Override
        public void onBindViewHolder(@NonNull Holder holder, int position, @NonNull List<Object> payloads) {
            if (payloads.isEmpty()) {
                onBindViewHolder(holder, position);
                return;
            }
            //更新某个控件,比如说只需要更新时间信息,其他不用动
            CountDownTimerBean bean = mList.get(position);
            long day = bean.getTotalTime() / (1000 * 60 * 60 * 24);
            long hour = (bean.getTotalTime() / (1000 * 60 * 60) - day * 24);
            long min = ((bean.getTotalTime() / (60 * 1000)) - day * 24 * 60 - hour * 60);
            long s = (bean.getTotalTime() / 1000 - day * 24 * 60 * 60 - hour * 60 * 60 - min * 60);
            holder.tvTime.setText("剩余时间: " + day + "天" + hour + "小时" + min + "分" + s + "秒");
            holder.btnAction.setText(bean.isPause() ? "开始" : "暂停");
            holder.btnAction.setEnabled(bean.getTotalTime() != 0);
        }

    2.销毁资源操作:

       /**
         * 销毁资源
         */
        public void destroy() {
            mHandler.removeMessages(1);
            if (mTimer != null) {
                mTimer.cancel();
                mTimer.purge();
                mTimer = null;
            }
        }
    • RecyclerView.Adapter部分源码
    public class CountDownTimerAdapter extends RecyclerView.Adapter<CountDownTimerAdapter.Holder> {
        private static final String TAG = "CountDownTimerAdapter->";
        private List<CountDownTimerBean> mList;//数据
        private Handler mHandler;//线程调度,用来更新列表
    
        private Timer mTimer;
        private MyTask mTask;
    
        public CountDownTimerAdapter() {
            mList = new ArrayList<>();
            mHandler = new Handler(Looper.getMainLooper()) {
                @Override
                public void handleMessage(Message msg) {
                    switch (msg.what) {
                        case 1:
                            notifyItemChanged(msg.arg1, "update-time");
                            break;
                    }
                }
            };
            mTask = new MyTask();
        }
    
        public void bindAdapterToRecyclerView(@NonNull RecyclerView view) {
            view.setAdapter(this);
        }
    
        /**
         * 设置新的数据源
         *
         * @param list 数据
         */
        public void setNewData(@NonNull List<CountDownTimerBean> list) {
            destroy();
            mList.clear();
            mList.addAll(list);
            notifyDataSetChanged();
            if (mTimer == null) {
                mTimer = new Timer();
            }
            mTimer.schedule(mTask, 0, 1000);
        }
    
        /**
         * 销毁资源
         */
        public void destroy() {
            mHandler.removeMessages(1);
            if (mTimer != null) {
                mTimer.cancel
首页 上一页 1 2 3 下一页 尾页 1/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇Android basics 下一篇抓出卡顿元凶,从分析掉帧开始

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目