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

ListView重复显示同一数据行问题求助(附核心代码)

解决ListView重复显示同一行数据的问题

先给你揪出核心问题,咱们一步步来搞定:

1. SQL查询产生笛卡尔积(这是重复显示的根本原因)

你写的SQL隐式JOIN里,没有关联TABLE_LIGNE(别名L)和其他表的条件,这会导致数据库返回笛卡尔积结果——简单说就是L表的每一行都会和其他表关联后的结果强制匹配,比如如果L表有5条数据,其他表关联后只有1条有效数据,最终就会返回5条完全重复的记录,这就是你看到ListView重复5次的直接原因。

修改你的SQL查询,补充L表和其他表的关联条件(请根据你的实际表结构调整关联字段):

SELECT Q." + KEY_QUESTION + " ,L." + KEY_LIGNE + " , U." + KEY_NOM + " , A." + KEY_DATE + " , A. " + KEY_REPONSE + " 
FROM "+ TABLE_LIGNE + " L
JOIN " + TABLE_ANSWER + " A ON L.你的L表关联字段 = A.对应A表关联字段 -- 必须补全L和其他表的关联逻辑
JOIN " + TABLE_QUESTION + " Q ON Q." + KEY_ID_QUESTION + " = A." + KEY_ID_QUESTION + " 
JOIN " + TABLE_USER + " U ON A." + KEY_MATRICULE + " = U." + KEY_MATRICULE

提示:一定要确保所有JOIN的表都有合理的关联条件,不然笛卡尔积会一直导致重复数据。

2. 调整Adapter初始化与数据填充的顺序(避免潜在坑)

你当前的代码是先创建MyAdapter,再往histList里塞数据,虽然最后调用了setAdapter,但这个顺序容易导致数据不同步的问题。建议调整为:

// 先清空列表,避免旧数据干扰
histList.clear();
mCsr = openhelper.getTableHistoAsCursor();
int rows = mCsr.getCount();
if (rows == 0 ){
    Toast.makeText(Historian.this, "Pas d'historique disponible", Toast.LENGTH_SHORT).show();
} else {
    while (mCsr.moveToNext()){
        histo = new Historique(mCsr.getString(0).toString(),mCsr.getString(1).toString(), 
                               mCsr.getString(2).toString(),mCsr.getString(3).toString(),mCsr.getString(4).toString());
        histList.add(histo);
    }
}
// 等数据完全填充后,再创建Adapter并绑定到ListView
final MyAdapter adapter = new MyAdapter (this, R.layout.adapter_view_layout,histList);
mListView.setAdapter(adapter);

3. 优化Adapter的getView方法(提升性能)

你的getView每次都重新inflate布局,没有复用convertView,虽然不是重复问题的原因,但会导致ListView滚动卡顿,建议改成复用写法:

@Override
public View getView(int position, View convertedView, ViewGroup parent) {
    ViewHolder holder;
    // 复用convertView,减少布局加载次数
    if (convertedView == null) {
        convertedView = mInflat.inflate(mVRessId, parent, false);
        holder = new ViewHolder();
        holder.name = convertedView.findViewById(R.id.hnom);
        holder.quest = convertedView.findViewById(R.id.hques);
        holder.rep = convertedView.findViewById(R.id.hrep);
        holder.date = convertedView.findViewById(R.id.hdate);
        convertedView.setTag(holder);
    } else {
        holder = (ViewHolder) convertedView.getTag();
    }
    
    Historique histor = hist.get(position);
    if (histor != null){
        holder.name.setText(""+histor.getNom()+ ": "+histor.getLigne());
        holder.quest.setText(histor.getQuest());
        holder.rep.setText(histor.getRep());
        holder.date.setText(histor.getDate().toString());
    }
    return convertedView;
}

// 内部ViewHolder类,缓存控件引用
static class ViewHolder {
    TextView name;
    TextView quest;
    TextView rep;
    TextView date;
}

先解决SQL的关联问题,这是重复显示的核心,再调整代码顺序和优化Adapter,应该就能彻底解决你的问题了。

内容的提问来源于stack exchange,提问作者Master49

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 08:14:24