最近一直被需求赶着走,有些功能经过测试上线后就没再审查。闲下来还是重新优化下老代码,温故而知新,还是有点收获和进步的
团购这种促销方式已经很普遍,尤其是大家熟悉的”并夕夕”更是玩的很6。现在我们就要实现一个团购倒计时列的表,并以“剩余:09:12:24.8”这种样式来展示该团距离结束时间的倒计时。
首先,有关时间变化的,首先想到TimerTask +计时器这个定时器组合,列表不用多说RecyclerView。其中涉及到UI更新,所以需要一个处理程序来更新项目。
初步我们会想到两种方式:
-
<李>每个项目使用一个定时器,更新项目李>
<李>使用一个定时器,更新数据源,更新项目李>
两种方法各有利弊,后面我们再具体通过演示对比。
其次,由于Android系统时间可被更改,所以要求我们不能单纯的直接通过后端返回的groupFinishTime减去当前系统时间系统。currentTimeMillis来作为要展示的剩余时间,所以我们首先在对接口时候记得跟后端同学约定好,大佬请直接传给我剩余的时间(单位是秒还是毫秒呢?都可以,不过大部分都会给秒)
<强>想想还有什么坑没想到强>
-
<李>后端直接给我返回了个还剩1秒咋办?莫得办法,这逻辑如果后端严谨他们会帮你处理掉很多临界时间点╮(╯_╰)╭,要么我们在接收到数据时候就做好过滤。李>
<李>从后端拿到数据的网络耗时+解析到展现耗时(即我的计时器从什么时候开始计时,以及初始化到启动的消耗)
其实Android本身就有一个自己的倒计时类:CountDownTimer,内部实现也是通过处理器实现,加上注释共157行,而且计算了程序内部消耗时间李> <李>列表是否支持下拉刷新,上拉加载?刷新之后数据是否会导致布局错乱,这些都需要我们考虑。李> <李> RecyclerView的缓存机制对不在屏幕内和重新回到屏幕内数据的影响李> <李>用到计时器肯定要考虑内存开销和内存泄漏李>
综上,我们确定了我们要做的东西:
-
<李>布局:SwipeRefreshLayout + RecyclerView李>
<李>计时器:CountDownTimer/TimerTask李>
<李>接口参数:groupLeftSecond(必须),groupFinishTime(最好也有),leftMemberCount(还差x人),leaderAvater(团长头像)李>
好的,那么我们就照着并夕夕的页面做一个吧
<强> 1。每一个项目个CountDownTimer 强>
关键代码(芬兰湾的科特林)
类GroupListAdapter(私人val mContext:上下文):RecyclerView.Adapter() { 私人var rList: List & # 63;=零 私人val countDownMap: SparseArray & # 63; 私人var mPostion: Int=0 私人var timesList: MutableList =ArrayList () init { countDownMap=SparseArray () } 乐趣setGroupList(列表:List & # 63;) { 这一点。rList=列表 如果(rList& # 63; .size ! !比;0){ timesList=ArrayList () (项目在rList ! !) { timesList.add ( 项。leftSecond * 1000 + System.currentTimeMillis () ) } } }//避免内存泄漏 乐趣cancelTimers () { 如果(countDownMap==null) { 返回 } (我在0直到countDownMap.size ()) { val cdt=countDownMap.get (countDownMap.keyAt(我)) cdt # 63; .cancel () } } 覆盖乐趣> init { mTask=CountTask () mHandler=对象:处理程序(Looper.getMainLooper ()) { 覆盖有趣handleMessage(味精:消息# 63;){ 如果(味精# 63;。什么==1){ 如果(rList& # 63; .size ! !比;0){ notifyItemChanged (msg.arg1 rList ! ! [msg.arg1]) } } } } }
初始化列表数据
乐趣setGroupList(列表:List& # 63;) { 这一点。rList=列表 如果(rList& # 63; .size ! !比;0){ cancelTimers () timesList=ArrayList () (项目在rList ! !) { timesList.add ( 项。leftSecond * 1000 ) } mTimer=计时器() mTask=CountTask () mTimer& # 63;。计划(mTask, 0, 100) } } 乐趣cancelTimers () { mHandler.removeMessages (1) mTimer& # 63; .cancel () mTimer& # 63; .purge () mTimer=零 } Android RecyclerView实现拼团倒计时列表实例代码