You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 11:48:34