日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術文章
文章詳情頁

解決Android-RecyclerView列表倒計時錯亂問題

瀏覽:168日期:2022-09-22 18:38:06

前言

轉眼間距離上次寫博客已是過了一個年輪,期間發生了不少事;經歷了離職、找工作,新公司的第一版項目上線。現在總算是有時間可以將遇到的問題梳理下了,后期有時間也會分享更多的東西~~

場景

今天分享的問題是當在列表里面顯示倒計時,這時候滑動列表會出現時間顯示不正常的問題。首先關于倒計時我們需要注意的問題有以下幾方面:

在RecyclerView中ViewHolder的復用導致的時間亂跳的問題。

滑動列表時倒計時會重置的問題。

在退出頁面后定時器的資源釋放問題,這里我使用的是用系統自帶的CountDownTimer

ps:這里我們討論的是對倒計時要求不是很嚴格的場景,對于用戶手動修改系統時間這種操作沒法預計;對于淘寶秒殺這種業務場景建議是實時不斷請求后臺拿取正確時間,對應的接口盡量設計簡單,響應數據更快。

接下來通過代碼具體了解:

代碼

// 適配器public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> { //服務器返回數據 private List<TimeBean> mDatas; //退出activity時關閉所有定時器,避免造成資源泄漏。 private SparseArray<CountDownTimer> countDownMap; //記錄每次刷新時的時間 private long tempTime; public MyAdapter(Context context, List<TimeBean> datas) { mDatas = datas; countDownMap = new SparseArray<>(); } @Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_common, parent, false); return new ViewHolder(view); } @Override public void onBindViewHolder(final ViewHolder holder, int position) { final TimeBean data = mDatas.get(position); //記錄時間點 long timeStamp = System.currentTimeMillis() - tempTime; long time = data.getLeftTime() - timeStamp; //將前一個緩存清除 if (holder.countDownTimer != null) { holder.countDownTimer.cancel(); } if (time > 0) { //判斷倒計時是否結束 holder.countDownTimer = new CountDownTimer(time, 1000) {public void onTick(long millisUntilFinished) { holder.timeTv.setText(getMinuteSecond(millisUntilFinished));}public void onFinish() { //倒計時結束 holder.timeTv.setText('00:00');} }.start(); countDownMap.put(holder.timeTv.hashCode(), holder.countDownTimer); } else { holder.timeTv.setText('00:00'); } } @Override public int getItemCount() { if (mDatas != null && !mDatas.isEmpty()) { return mDatas.size(); } return 0; } public class ViewHolder extends RecyclerView.ViewHolder { public TextView timeTv; public CountDownTimer countDownTimer; public ViewHolder(View itemView) { super(itemView); timeTv = (TextView) itemView.findViewById(R.id.tv_time); } } public void setGetTime(long tempTime) { this.tempTime = tempTime; } /** * 將毫秒數換算成 00:00 形式 */ public static String getMinuteSecond(long time) { int ss = 1000; int mi = ss * 60; int hh = mi * 60; int dd = hh * 24; long day = time / dd; long hour = (time - day * dd) / hh; long minute = (time - day * dd - hour * hh) / mi; long second = (time - day * dd - hour * hh - minute * mi) / ss; String strMinute = minute < 10 ? '0' + minute : '' + minute; String strSecond = second < 10 ? '0' + second : '' + second; return strMinute + ':' + strSecond; } /** * 清空資源 */ public void cancelAllTimers() { if (countDownMap == null) { return; } for (int i = 0,length = countDownMap.size(); i < length; i++) { CountDownTimer cdt = countDownMap.get(countDownMap.keyAt(i)); if (cdt != null) {cdt.cancel(); } } }}

以上算是整個問題的核心代碼了;其中SparseArray<CountDownTimer> 用來保存列表里面的定時器,用于退出頁面時回收定時器。SparseArray是安卓特有的數據結構,建議多使用;data.getLeftTime() 是服務器返回的需要倒計時的時間,毫秒為單位。

問題一:ViewHolder的復用導致的數據錯亂

if (holder.countDownTimer != null) { holder.countDownTimer.cancel(); }

每次設置倒計時之前重置下倒計時即可解決。

問題二:滑動列表時倒計時會重置的問題

這個問題是由于解決問題一而導致的,因為列表滑動時離開屏幕的會被復用,這個時候我們會重新設置定時器,之前我是在倒計時里面記錄倒計時剩余的時間然后重新設值,但是還是會有問題;這里借用了系統時間來解決,也就是tempTime 這個值。

首先在服務器請求成功后回調里面設置這個值,如:

private MyAdapter adapter; @Override public void onHttpRequestSuccess(String url, HttpContext httpContext) { if (服務器返回數據) { adapter.setGetTime(System.currentTimeMillis()); }

相當于每次做刷新操作時獲取的都是系統當時的時間戳。

然后在adapter里面計算

long timeStamp = System.currentTimeMillis() - tempTime;

long time = data.getLeftTime() - timeStamp;

其中tempTime就是我們保存的系統當前時間戳,然后每次滑動列表時都會調用onBindViewHolder,所以timeStamp就是記錄的距離上次刷新經過了多少秒,然后用服務器返回的需要倒計時的時間減去經過的秒數就是還剩下的倒計時秒數。最后給定時器設置上就好了。

問題三:資源的釋放

在當前的activity中調用以下方法。

@Overrideprotected void onDestroy() { super.onDestroy(); if (adapter != null) { adapter.cancelAllTimers(); }}

好了,今天的分享就到這了,因為代碼比較簡單,布局都是一個Textview,所以沒有貼出來,需要代碼的可以留言~~

補充知識:Android 自定義倒計時,支持listview多item一起倒計時

項目中用到的兩種倒計時,一種是用CountDownTimer,但是這種方式在listview中就不是那么好用了,當listview 里面多個item都需要倒計時,就不可以用這種了,我這里想到用Thread 加handler來一起實現。如果大家還有好的倒計時方法,可以留言一起討論哦,由于代碼都是在項目中的,我就截取幾段代碼。

第一種 CountDownTimer:

主要自定義一個類繼承CountDownTimer,在啟動的時候調用start(),倒計時完畢調用canel()方法。

time = new TimeCount(remainingTime, 1000);//構造CountDownTimer對象time.start();//開始計時class TimeCount extends CountDownTimer { public TimeCount(long millisInFuture, long countDownInterval) { super(millisInFuture, countDownInterval); } @Override public void onFinish() {//計時完畢時觸發 if (isDead) {remainingTime = 90000;ColorStateList colorStateList = getResources().getColorStateList(R.color.button_send_code_text2_selector);getCode.setTextColor(colorStateList);getCode.setText(R.string.register_tip7);getCode.setEnabled(true); } } @Override public void onTick(long millisUntilFinished) {//計時過程顯示 if (isDead) {getCode.setEnabled(false);getCode.setTextColor(getResources().getColor(R.color.grey5));remainingTime = millisUntilFinished;getCode.setText(millisUntilFinished / 1000 + '秒后重發'); } } }

第二種 Thread 加handler

創建一個新的線程,每秒中減一次時間,然后在handler中每秒中刷新一次界面就可以看到倒計時的效果。

private Thread thread; //條目倒計時 public void start() { thread = new Thread() { public void run() {while (true) { try { if (list != null) { for (InvestProjectVo item : list) {if(item.remainOpenTime == 0){ item.status = 0;}if(item.remainOpenTime > 0){ item.remainOpenTime = item.remainOpenTime - 1;} } } sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); }} } }; thread.start(); }

在adapter的getview()方法中,判斷倒計時時間是否大于0,如果大于零可以繼續顯示倒計時時間

if (vo.remainOpenTime != 0 && vo.remainOpenTime > 0) { viewCache.showProjectFullIcon.setVisibility(View.GONE); viewCache.projectProgress.setVisibility(View.GONE); viewCache.showTimer.setVisibility(View.VISIBLE); long tempTime = vo.remainOpenTime; long day = tempTime / 60 / 60 / 24; long hours = (tempTime - day * 24 * 60 * 60) / 60 / 60; long minutes = (tempTime - day * 24 * 60 * 60 - hours * 60 * 60) / 60; long seconds = (tempTime - day * 24 * 60 * 60 - hours * 60 * 60 - minutes * 60); if (minutes > 0) { viewCache.timer.setText(minutes + '分' + seconds + '秒'); } else { viewCache.timer.setText(seconds + '秒'); } }else{ viewCache.showProjectFullIcon.setVisibility(View.GONE); viewCache.projectProgress.setVisibility(View.VISIBLE); viewCache.showTimer.setVisibility(View.GONE); }

在handler中每秒鐘刷新一次界面

mHandler.sendEmptyMessageDelayed(2586221,1000);

adapter.notifyDataSetChanged();//每隔1毫秒更新一次界面,如果只需要精確到秒的倒計時此處改成1000即可mHandler.sendEmptyMessageDelayed(2586221,1000);

以上這篇解決Android-RecyclerView列表倒計時錯亂問題就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支持好吧啦網。

標簽: Android
相關文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
免费的成人av| 色爱综合网欧美| 婷婷精品视频| 亚洲乱亚洲高清| 国产欧美高清| 色综合狠狠操| 国产精品毛片一区二区三区| 蜜臀久久久久久久| 久久精品二区亚洲w码| 免费看av不卡| 亚洲一区二区三区无吗| 国产精品久久久久久久久免费高清| 日韩免费精品| 日韩欧美三级| 7777精品| 少妇精品导航| 日韩高清不卡一区二区| 国产精品13p| 日本不卡视频在线| 日韩欧美中文| 欧美日本精品| 亚洲少妇在线| 日韩国产一区| 国产亚洲高清在线观看| 婷婷丁香综合| 97精品国产福利一区二区三区| 首页亚洲欧美制服丝腿| 免费在线成人| 蜜臀av在线播放一区二区三区| 麻豆免费精品视频| 亚洲三级国产| 香蕉精品视频在线观看| 国产videos久久| 国产日韩一区二区三区在线 | 久久亚洲美女| 日本综合字幕| 久久精品三级| 欧美日韩中出| 尤物在线精品| 日韩欧美一区二区三区免费看| 日日夜夜免费精品视频| 国产精品人人爽人人做我的可爱| 天堂√中文最新版在线| 久久不卡国产精品一区二区| 美国三级日本三级久久99| 欧美日韩国产高清电影| 91精品国产成人观看| 精品日本视频| 精品一区二区三区亚洲| 欧美激情福利| 久久99蜜桃| 国产中文欧美日韩在线| 国际精品欧美精品| 欧美天堂在线| 国产乱码精品一区二区亚洲| 日韩激情av在线| 国产精品调教视频| 精品亚洲自拍| 久久夜夜操妹子| 欧美日韩日本国产亚洲在线 | 男女性色大片免费观看一区二区 | 视频一区日韩精品| 青草久久视频| 精品国产日韩欧美精品国产欧美日韩一区二区三区| 日本在线不卡视频| 欧美黄页在线免费观看| 91av亚洲| 免费在线看一区| 欧美另类中文字幕 | 97精品在线| 久久精品影视| 久久婷婷亚洲| 亚洲三级av| 久久69成人| 好看不卡的中文字幕| 91精品在线免费视频| 精品久久97| 老鸭窝毛片一区二区三区| 日本成人中文字幕在线视频| 精品91福利视频| 亚洲一区二区三区四区五区午夜| 欧美日韩精品一区二区三区视频 | 国产亚洲字幕| 国产一区日韩欧美| 国产欧美啪啪| 青青久久av| 国产精品一区二区三区美女| 欧美午夜精彩| 国产福利资源一区| 亚洲欧美网站| 啪啪国产精品| 免费观看亚洲天堂| 亚洲精品自拍| 日韩天堂av| 久久久精品日韩| 久久精品伊人| 欧美久久亚洲| 在线一区二区三区视频| 欧美日韩一区二区三区视频播放| 国产日韩三级| 日韩精品一级二级| 五月综合激情| 婷婷精品视频| 999久久久精品国产| 成人国产精品一区二区网站| 日韩不卡免费视频| 亚洲尤物av| 亚洲开心激情| 色综合视频一区二区三区日韩| 夜夜精品视频| aa国产精品| 六月丁香综合| 蜜桃一区二区三区在线| 欧美特黄一级| 美女久久网站| 亚洲韩日在线| 亚洲激情中文| 美女尤物久久精品| 亚洲欧美网站在线观看| 亚洲理论在线| 欧美一区成人| 久久一区亚洲| 欧美三级精品| 99在线观看免费视频精品观看| 欧美精品激情| 亚洲va久久| 国产精品一区免费在线| 精品久久网站| 日本精品影院| 丝袜国产日韩另类美女| 午夜国产一区二区| 蜜桃视频一区二区三区| 日韩黄色免费网站| 精品无人区麻豆乱码久久久| 国产成人精品亚洲日本在线观看| 久久一区二区三区喷水| 亚洲人妖在线| 国产精品成久久久久| 亚洲二区三区不卡| 日本精品另类| 欧美成人a交片免费看| 亚洲一区二区三区免费在线观看| 日韩高清在线不卡| 精品亚洲免a| 美女黄网久久| 国产精品xxx| 亚洲欧洲一区二区天堂久久| 国产精品久一| 99精品99| 色综合五月天| 亚洲精品观看| 午夜av成人| 国产美女精品视频免费播放软件| 日韩av首页| 国产精品探花在线观看| 美女亚洲一区| 国产一区三区在线播放| 天堂av一区| 2023国产精品久久久精品双| 国产欧美日韩影院| 国产中文一区| 欧美激情日韩| 日韩精品国产欧美| 影音国产精品| 视频福利一区| 精品国产午夜| 国产精品探花在线观看| 免费人成在线不卡| 99精品美女| zzzwww在线看片免费| 国产丝袜一区| 日韩久久一区| 亚洲日产国产精品| 美女精品在线观看| 欧美精品羞羞答答| 国产美女高潮在线| 欧美xxxx中国| 久久中文精品| 美女视频黄 久久| 国产精品久久久久9999高清| 日韩精品亚洲专区在线观看| 六月婷婷一区| 蜜桃传媒麻豆第一区在线观看| 欧美高清一区| 自拍日韩欧美| 丝袜美腿亚洲色图| 免费精品视频| 蜜桃视频在线观看一区| 免费久久99精品国产| 亚洲一区免费| 国产精品毛片在线| 日韩在线一区二区| 视频精品一区| 国产精品亚洲一区二区在线观看| 午夜精品福利影院| 国产精品日本一区二区不卡视频 | 欧美丰满日韩| 国产一区二区三区亚洲| 高清久久精品| 999国产精品永久免费视频app|