ListView自定义适配器Try-Catch块内TextView初始化后不显示数据求助
问题分析与解决方案
核心问题:TextView赋值逻辑错误
你代码里最直接的bug是没有调用TextView的setText()方法,而是直接给ViewHolder里的TextView变量重新赋值,导致原来的控件引用被覆盖,自然不会显示任何内容。
错误写法:
viewHolder.ps_m = setPatientStatus(followupModel.PtStatus);
正确写法:
viewHolder.ps_m.setText(setPatientStatus(followupModel.PtStatus));
所有类似viewHolder.xxx = setPatientStatus(...)的代码都要改成调用setText()的形式。
优化方案:避免UI线程操作数据库
getView运行在UI线程,同步调用dbHelper.GetFollowupData()会阻塞UI,造成列表滑动卡顿甚至ANR,必须改成异步加载:
1. 预加载数据到数据源
在Adapter初始化时,通过异步任务一次性加载所有随访数据,给AdmissionModel添加followupData字段缓存结果,getView里直接使用缓存好的数据,无需实时查询数据库。
2. 单条数据异步加载(无法预加载时)
如果必须在getView中加载单条数据,用AsyncTask或Coroutine实现异步查询(Java推荐AsyncTask,Kotlin推荐Coroutine):
private class LoadFollowupTask extends AsyncTask<String, Void, List<FollowupModel>> { private AdmissionModel admissionModel; private AdmissionViewHolder viewHolder; public LoadFollowupTask(AdmissionModel model, AdmissionViewHolder holder) { this.admissionModel = model; this.viewHolder = holder; } @Override protected List<FollowupModel> doInBackground(String... params) { String previousDay = params[0]; String toDay = params[1]; return dbHelper.GetFollowupData(admissionModel.NtfSL, previousDay, toDay); } @Override protected void onPostExecute(List<FollowupModel> followupModels) { super.onPostExecute(followupModels); // 清空旧数据 viewHolder.ps_m.setText(""); viewHolder.ps_e.setText(""); viewHolder.ps_n.setText(""); viewHolder.ts_m.setText(""); viewHolder.ts_e.setText(""); viewHolder.ts_n.setText(""); if(followupModels.size()>0){ Map<String, List<FollowupModel>> groupByDateList = Stream.of(followupModels).collect( Collectors.groupingBy(e->e.FollowupDateyyyMMdd)); for (String dataKey : groupByDateList.keySet()){ if(dataKey.equals(params[0])){ for (FollowupModel followupModel : groupByDateList.get(dataKey)){ if(followupModel.Type == 1){ viewHolder.ps_m.setText(setPatientStatus(followupModel.PtStatus)); }else if(followupModel.Type == 2){ viewHolder.ps_e.setText(setPatientStatus(followupModel.PtStatus)); }else if(followupModel.Type == 3){ viewHolder.ps_n.setText(setPatientStatus(followupModel.PtStatus)); } } }else if(dataKey.equals(params[1])){ for (FollowupModel followupModel : groupByDateList.get(dataKey)){ if(followupModel.Type == 1){ viewHolder.ts_m.setText(setPatientStatus(followupModel.PtStatus)); }else if(followupModel.Type == 2){ viewHolder.ts_e.setText(setPatientStatus(followupModel.PtStatus)); }else if(followupModel.Type == 3){ viewHolder.ts_n.setText(setPatientStatus(followupModel.PtStatus)); } } } } } } }
在getView中启动任务:
try { SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd"); Date date = new Date(); String toDay = formatter.format(date); Calendar cal = Calendar.getInstance(); cal.add(Calendar.DATE, -1); String previousDay = formatter.format(cal.getTime()); new LoadFollowupTask(admissionModel, viewHolder).execute(previousDay, toDay); } catch (Exception e) { e.printStackTrace(); }
其他优化点
- 处理数据为空的情况:在设置数据前清空TextView,避免ListView复用控件时显示旧数据。
- 线程安全的日期格式化:
SimpleDateFormat线程不安全,用ThreadLocal包装:
private static ThreadLocal<SimpleDateFormat> dateFormatter = new ThreadLocal<SimpleDateFormat>() { @Override protected SimpleDateFormat initialValue() { return new SimpleDateFormat("yyyy-MM-dd"); } }; // 使用时 String toDay = dateFormatter.get().format(date);
- 简化数据分组逻辑:用双层Map直接存储日期+类型对应的状态,避免嵌套遍历:
Map<String, Map<Integer, String>> statusMap = new HashMap<>(); for(FollowupModel model : followupModelList) { statusMap.computeIfAbsent(model.FollowupDateyyyMMdd, k -> new HashMap<>()) .put(model.Type, setPatientStatus(model.PtStatus)); } // 直接取值设置 viewHolder.ps_m.setText(statusMap.getOrDefault(previousDay, new HashMap<>()).getOrDefault(1, ""));
修复后的核心代码片段
try { SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd"); Date date = new Date(); String toDay = formatter.format(date); Calendar cal = Calendar.getInstance(); cal.add(Calendar.DATE, -1); String previousDay = formatter.format(cal.getTime()); // 清空旧数据 viewHolder.ps_m.setText(""); viewHolder.ps_e.setText(""); viewHolder.ps_n.setText(""); viewHolder.ts_m.setText(""); viewHolder.ts_e.setText(""); viewHolder.ts_n.setText(""); List<FollowupModel> followupModelList = dbHelper.GetFollowupData(admissionModel.NtfSL,previousDay,toDay); if(followupModelList.size()>0){ Map<String, List<FollowupModel>> groupByDateList = Stream.of(followupModelList).collect( Collectors.groupingBy(e->e.FollowupDateyyyMMdd)); for (String dataKey : groupByDateList.keySet()){ if(dataKey.equals(previousDay)){ for (FollowupModel followupModel : groupByDateList.get(dataKey)){ if(followupModel.Type == 1){ viewHolder.ps_m.setText(setPatientStatus(followupModel.PtStatus)); }else if(followupModel.Type == 2){ viewHolder.ps_e.setText(setPatientStatus(followupModel.PtStatus)); }else if(followupModel.Type == 3){ viewHolder.ps_n.setText(setPatientStatus(followupModel.PtStatus)); } } }else if(dataKey.equals(toDay)){ for (FollowupModel followupModel : groupByDateList.get(dataKey)){ if(followupModel.Type == 1){ viewHolder.ts_m.setText(setPatientStatus(followupModel.PtStatus)); }else if(followupModel.Type == 2){ viewHolder.ts_e.setText(setPatientStatus(followupModel.PtStatus)); }else if(followupModel.Type == 3){ viewHolder.ts_n.setText(setPatientStatus(followupModel.PtStatus)); } } } } } } catch (ParseException e) { e.printStackTrace(); }
内容的提问来源于stack exchange,提问作者Hossain Kabir
相关产品推荐
相关产品推荐

