Android:一个线程玩转商品列表所有item的倒计时器,并对Adapter进行单控件刷新优化...
所以這次我還是會跟大家講一下關(guān)于商城的一個需求------商品的倒計時器。 或者有人會說,商品的一個倒計時很簡單,但是我這次的需求是一個商品列表,每個商品都需要有一個自己的計時器。首先我們看看需求效果:
ScreenRecord_2016-12-04-16-00-26.mp4_1480855963.gif
看到gif圖大家都應(yīng)該大概知道我們要做的是一個商品列表的所有商品的倒計時,而且每個商品都擁有自己的倒計時時間。其實,剛剛看到這樣的需求時,我就會第一時間去想用網(wǎng)上什么第三方庫去幫我解決這個問題。但看過我之前文章的朋友都應(yīng)該知道,我本人并不喜歡用第三方的庫,因為我覺得要真正提高能力需要的是自己動手。所以最后我還是決定應(yīng)用自己掌握的最簡單的方式去解決這個問題。下面講講我自己的做法: 不想聽我啰嗦的同學(xué)們可以直接下載源碼自己研究一下,源碼下載鏈接 倒計時需求.png
JavaBean.png
看到上面的一條RecyclerView的倒計時器,當(dāng)時我第一時間是想起我要不要在RecyclerView的adapter中開線程去控制每個item。確實,在摸索階段我試過這樣去做,但這樣去做我發(fā)現(xiàn)問題就來了: 1.在adapter開線程,我到底需要多少個線程,什么時候停止這些線程; 2.RecyclerView的adapter里面有holder的復(fù)用,那我開的線程怎么去控制呢。 我自己想了一會,覺得這種方法并不能行得通,因為太多問題我無法控制,而且就算做出來這樣的倒計時器絕對把界面卡出翔來。正在我很懊惱的時候,坐我旁邊的一位同事說,你看能不能不要在adapter那里開線程,看能不能只開一個線程去處理所有的數(shù)據(jù)。聽到這個,我就突然間恍然大悟。下面就講講我想到了什么和具體的做法: 因為我一開始就進入一個誤區(qū),或者可以說是一個思維定勢。我一開始想的是對每個商品也就是RecyclerView的每個item的數(shù)據(jù)進行單獨的處理,并沒有把他們想到一塊去,把所有數(shù)據(jù)一次過做處理,所以我想到的是把所有商品的數(shù)據(jù)一塊去處理,用一個線程就可以做到想要的效果。 下面就開始講講我的做法: 1.先去JavaBean那里定義兩個極為關(guān)鍵的屬性:
定義兩個極為關(guān)鍵的存儲數(shù)據(jù)屬性.png
然后自己寫出他們的get、set方法就好。 2.算出系統(tǒng)時間與活動結(jié)束時間的時間差,并保存到每個商品中去: 從后臺拿到的數(shù)據(jù)大致是這樣的.png
從后臺拿到的數(shù)據(jù)大致是這樣的,這里我只是為了演示一下,所以插進一些本地數(shù)據(jù)。 算出并返回時間差.png 算出時間差并保存在每個商品的counttime屬性.png
3.該去寫寫我們的線程和handler了: class MyThread implements Runnable{ //用來停止線程 boolean endThread; List<RecommendActivitiesBean.ResultListBean> mRecommendActivitiesList; public MyThread(List<RecommendActivitiesBean.ResultListBean> mRecommendActivitiesList){ this.mRecommendActivitiesList = mRecommendActivitiesList; } @Override public void run() { while(!endThread){ try{ //線程每秒鐘執(zhí)行一次 Thread.sleep(1000); //遍歷商品列表 for(int i = 0;i < mRecommendActivitiesList.size();i++){ //拿到每件商品的時間差,轉(zhuǎn)化為具體的多少天多少小時多少分多少秒 //并保存在商品time這個屬性內(nèi) long counttime = mRecommendActivitiesList.get(i).getCountTime(); long days = counttime / (1000 * 60 * 60 * 24); long hours = (counttime-days*(1000 * 60 * 60 * 24))/(1000* 60 * 60); long minutes = (counttime-days*(1000 * 60 * 60 * 24) -hours*(1000* 60 * 60))/(1000* 60); long second = (counttime-days*(1000 * 60 * 60 * 24) -hours*(1000* 60 * 60)-minutes*(1000*60))/1000; //并保存在商品time這個屬性內(nèi) String finaltime = days + "天" + hours + "時" + minutes + "分" + second + "秒"; mRecommendActivitiesList.get(i).setTime(finaltime); //如果時間差大于1秒鐘,將每件商品的時間差減去一秒鐘, // 并保存在每件商品的counttime屬性內(nèi) if(counttime > 1000) { mRecommendActivitiesList.get(i).setCountTime(counttime - 1000); } } Message message = new Message(); message.what = 1; //發(fā)送信息給handler handler.sendMessage(message); }catch (Exception e){ } } } } handler.png
就是一個普通的線程和handler,我相信一般初學(xué)java或者android的人都會寫出來。我在這個線程里:
1.每一秒鐘拿商品自己的時間差counttime出來計算還剩下具體的多少天多少小時多少分多少秒; 2,然后把這個String字符串保存在第一步定義的time屬性當(dāng)中, 如果時間差大于1秒鐘,那就在每個商品的時間差counttime中減去1秒鐘并再次去保存起來; 3.發(fā)送消息通知handler去刷新adapter。 4.最后只需要我們?nèi)dapter的TextView中setText就完成了: TextView的setText.png
其實到這里,我們要的倒計時功能已經(jīng)基本實現(xiàn)。但是,我的師兄就來吹毛求疵了。我告訴他我的想法和做法,他基本認(rèn)同了,但是他覺得handler里面每一秒鐘調(diào)用notifyDataSetChanged方法去刷新adapter并不太妥。因為每個item中,你只需要一個TextView去刷新時間,其他控件并不需要刷新。所以我聽了他的想法,決定把它一并實現(xiàn)了。下面就是我對adapter的一些刷新優(yōu)化處理: 1.在onBindViewHolder的時候為每個holder綁定當(dāng)前顯示的position, holder.setDataPosition(position)(方法是自己定義的); 2.考慮到holder的復(fù)用性,同時將這個holder保存到adapter中的一個List中(注意要判斷是否保存過該holder了); 3.在adapter定義一個方法,方法中去遍歷上面的List,然后刷新顯示倒計時的TextView。 這是師兄給我的一些思路,下面就是具體的實現(xiàn): 1.在onBindViewHolder的時候為每個holder綁定當(dāng)前顯示的position, holder.setDataPosition(position)(方法是自己定義的):
setDataPosition方法.png
2.考慮到holder的復(fù)用性,同時將這個holder保存到adapter中的一個List中(注意要判斷是否保存過該holder了); 保存holder的List.png 將holder保存在list里面.png
3.在adapter定義一個方法,方法中去遍歷上面的List,然后刷新顯示倒計時的TextView: 遍歷list,刷新相應(yīng)holder的TextView.png
4.最后把handler的刷新adapter的notifyDataSetChanged方法換成自己在adapter寫的notifyData方法: 自己寫的notifyData方法.png 會動的倒計時器效果.png
很簡單,我們只用了一個線程和兩個保存數(shù)據(jù)的屬性又完成了一個看起來很麻煩的倒計時器問題,并且用一個極為簡便的方法去優(yōu)化了刷新RecyclerView可能會出現(xiàn)的界面卡頓問題,看上去非常nice。有興趣學(xué)習(xí)的同學(xué)們可以去下載源碼繼續(xù)研究,有什么問題可以向我提出來一起研究、一起進步!
總結(jié)
以上是生活随笔為你收集整理的Android:一个线程玩转商品列表所有item的倒计时器,并对Adapter进行单控件刷新优化...的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 线上服务器登记的要点
- 下一篇: WPF,强制捕获鼠标事件,鼠标移出控件外