电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

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

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

瀏覽:111日期: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
相關文章:
主站蜘蛛池模板: Magnescale探规,Magnescale磁栅尺,Magnescale传感器,Magnescale测厚仪,Mitutoyo光栅尺,笔式位移传感器-苏州连达精密量仪有限公司 | 雨水收集系统厂家-雨水收集利用-模块雨水收集池-徐州博智环保科技有限公司 | 青岛球场围网,青岛车间隔离网,青岛机器人围栏,青岛水源地围网,青岛围网,青岛隔离栅-青岛晟腾金属制品有限公司 | 大学食堂装修设计_公司餐厅效果图_工厂食堂改造_迈普装饰 | 企业管理培训,企业培训公开课,企业内训课程,企业培训师 - 名课堂企业管理培训网 | PVC地板|PVC塑胶地板|PVC地板厂家|地板胶|防静电地板-无锡腾方装饰材料有限公司-咨询热线:4008-798-128 | 法兰连接型电磁流量计-蒸汽孔板节流装置流量计-北京凯安达仪器仪表有限公司 | 集装箱箱号识别_自重载重图像识别_铁路车号自动识别_OCR图像识别 | 数字展示在线_数字展示行业门户网站| 电动液压篮球架_圆管地埋式篮球架_移动平箱篮球架-强森体育 | 黑田精工电磁阀-CAMMOZI气缸-ROSS电磁-上海茂硕机械设备有限公司 | 筛分机|振动筛分机|气流筛分机|筛分机厂家-新乡市大汉振动机械有限公司 | 伸缩节_伸缩器_传力接头_伸缩接头_巩义市联通管道厂 | 退火炉,燃气退火炉,燃气热处理炉生产厂家-丹阳市丰泰工业炉有限公司 | 耐热钢-耐磨钢-山东聚金合金钢铸造有限公司 | 安徽泰科检测科技有限公司【官方网站】 | 奇酷教育-Python培训|UI培训|WEB大前端培训|Unity3D培训|HTML5培训|人工智能培训|JAVA开发的教育品牌 | 政府回应:200块在义乌小巷能买到爱情吗?——揭秘打工族省钱约会的生存智慧 | 德国BOSCH电磁阀-德国HERION电磁阀-JOUCOMATIC电磁阀|乾拓百科 | 临海涌泉蜜桔官网|涌泉蜜桔微商批发代理|涌泉蜜桔供应链|涌泉蜜桔一件代发 | 苏州教学设备-化工教学设备-环境工程教学模型|同科教仪 | 防爆正压柜厂家_防爆配电箱_防爆控制箱_防爆空调_-盛通防爆 | 钢衬四氟管道_钢衬四氟直管_聚四氟乙烯衬里管件_聚四氟乙烯衬里管道-沧州汇霖管道科技有限公司 | 防弹玻璃厂家_防爆炸玻璃_电磁屏蔽玻璃-四川大硅特玻科技有限公司 | 炭黑吸油计_测试仪,单颗粒子硬度仪_ASTM标准炭黑自销-上海贺纳斯仪器仪表有限公司(HITEC中国办事处) | 机制砂选粉机_砂石选粉机厂家-盐城市助成粉磨科技有限公司 | 广州企亚 - 数码直喷、白墨印花、源头厂家、透气无手感方案服务商! | 搅拌磨|搅拌球磨机|循环磨|循环球磨机-无锡市少宏粉体科技有限公司 | 雷达液位计_超声波风速风向仪_雨量传感器_辐射传感器-山东风途物联网 | 许昌奥仕达自动化设备有限公司 | 临沂招聘网_人才市场_招聘信息_求职招聘找工作请认准【马头商标】 | PCB厂|线路板厂|深圳线路板厂|软硬结合板厂|电路板生产厂家|线路板|深圳电路板厂家|铝基板厂家|深联电路-专业生产PCB研发制造 | 语料库-提供经典范文,文案句子,常用文书,您的写作得力助手 | 昆明网络公司|云南网络公司|昆明网站建设公司|昆明网页设计|云南网站制作|新媒体运营公司|APP开发|小程序研发|尽在昆明奥远科技有限公司 | 济南玻璃安装_济南玻璃门_济南感应门_济南玻璃隔断_济南玻璃门维修_济南镜片安装_济南肯德基门_济南高隔间-济南凯轩鹏宇玻璃有限公司 | 应急灯_消防应急灯_应急照明灯_应急灯厂家-大成智慧官网 | 防水套管厂家-柔性防水套管-不锈钢|刚性防水套管-天翔管道 | 书信之家_书信标准模板范文大全 最新范文网_实用的精品范文美文网 | 武汉高低温试验机-现货恒温恒湿试验箱-高低温湿热交变箱价格-湖北高天试验设备 | 临朐空调移机_空调维修「空调回收」临朐二手空调 | 浙江美尔凯特智能厨卫股份有限公司|