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
相关产品推荐
相关产品推荐

