Android利用RecyclerView实现列表倒计时效果
程序员文章站
2022-05-31 15:32:02
最近面试时,面试官问了一个列表倒计时效果如何实现,然后脑袋突然懵的了O(∩_∩)O,现在记录一下。 运行效果图 实现思路 实现方法主要有两个: 1.为每个开始倒计时的item启动一个定时器,再做更新item处理; 2.只启动一个定时器,然后遍历数据,再做再做更新item处理。 经过思考,包括性能、实 ......
最近面试时,面试官问了一个列表倒计时效果如何实现,然后脑袋突然懵的了o(∩_∩)o,现在记录一下。
运行效果图
实现思路
实现方法主要有两个:
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(); 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<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); } @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使用RecyclerView实现列表数据选择操作
-
Android利用CountDownTimer实现倒计时功能 Android实现停留5s跳转到登录页面
-
Android中RecyclerView实现多级折叠列表效果(TreeRecyclerView)
-
Android中RecyclerView实现多级折叠列表效果(二)
-
Android控件RecyclerView实现混排效果仿网易云音乐
-
Android Recyclerview实现水平分页GridView效果示例
-
Android利用RecyclerView实现全选、置顶和拖拽功能示例
-
Android studio listview实现列表数据显示 数据循环显示效果
-
android BottomSheetDialog新控件解析实现知乎评论列表效果(实例代码)
-
Android利用GridView实现单选效果