您现在的位置: 主页 > 嵌入式操作系统 > Android > Android利用RecyclerView实现列表倒计时效果
本文所属标签:
为本文创立个标签吧:

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

来源:net 网络用户发布,如有版权联系网管删除 2019-02-27 

最近面试时,面试官问了一个列表倒计时效果如何实现,然后脑袋突然懵的了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 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 {    private static final String TAG = "CountDownTimerAdapter->";    private List 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 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();            mTimer.purge();            mTimer = null;        }    }    @NonNull    @Override    public Holder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {        View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item_count_down_timer, viewGroup, false);        return new Holder(view);    }    @Override    public void onBindViewHolder(@NonNull Holder holder, int position, @NonNull List 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);    }    @Override    public void onBindViewHolder(@NonNull final Holder holder, int position) {        holder.ivIcon.setImageResource(R.mipmap.ic_launcher_round);        final 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);        holder.btnAction.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                if (bean.isPause()) {                    bean.setPause(false);                    holder.btnAction.setText("暂停");                } else {                    bean.setPause(true);                    holder.btnAction.setText("开始");                }            }        });    }    @Override    public int getItemCount() {        return mList.size();    }    class Holder extends RecyclerView.ViewHolder {        private ImageView ivIcon;        private TextView tvTime;        private Button btnAction;        Holder(@NonNull View itemView) {            super(itemView);            ivIcon = itemView.findViewById(R.id.iv_icon);            tvTime = itemView.findViewById(R.id.tv_time);            btnAction = itemView.findViewById(R.id.btn_action);        }    }    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);                }            }        }    }}

项目地址

源码



如有问题,欢迎及时沟通。



              查看评论 回复



嵌入式交流网主页 > 嵌入式操作系统 > Android > Android利用RecyclerView实现列表倒计时效果
 一个 实现 倒计时

"Android利用RecyclerView实现列表倒计时效果"的相关文章

围观()