ListView行点击更新异常:多行被修改的问题排查请求
问题分析与修复方案
你遇到的问题是ListView视图复用导致的状态残留,核心原因出在SiteAdapter的getView方法里:
ListView为了优化性能会复用滑出屏幕的item视图(也就是convertView)。你的代码只在site.isBarred()为true时给文本设置删除线,但完全没处理site.isBarred()为false的情况——这就导致之前被设置过删除线的视图被复用时,新的item即使不需要删除线,也会带着旧的状态,看起来像是“错误更新了多行”。
具体修复步骤
在SiteAdapter的getView方法中,补充处理site.isBarred()为false的场景,主动清除文本的删除线标记:
@Override public View getView(int position, View convertView, ViewGroup parent) { if(convertView == null){ convertView = LayoutInflater.from(getContext()).inflate(R.layout.row_site,parent, false); } SiteViewHolder viewHolder = (SiteViewHolder) convertView.getTag(); if(viewHolder == null){ viewHolder = new SiteViewHolder(); viewHolder.heure_supposee = convertView.findViewById(R.id.heure_supposee); viewHolder.libelle_site = convertView.findViewById(R.id.libelle_site); viewHolder.logo_telephone = convertView.findViewById(R.id.logo_phone); convertView.setTag(viewHolder); } Site site = getItem(position); viewHolder.heure_supposee.setText(site.getHeure_supposee()); viewHolder.libelle_site.setText(site.getLibelle_site()); // 先重置电话图标可见性,避免复用残留 viewHolder.logo_telephone.setVisibility(View.INVISIBLE); if (site.getSur_appel().equals("O")) { viewHolder.logo_telephone.setVisibility(View.VISIBLE); } // 处理删除线:存在则设置,不存在则清除 if (site.isBarred()) { viewHolder.libelle_site.setPaintFlags(Paint.STRIKE_THRU_TEXT_FLAG); } else { // 只清除删除线标记,保留文本其他可能的样式(比如粗体、斜体) viewHolder.libelle_site.setPaintFlags(viewHolder.libelle_site.getPaintFlags() & ~Paint.STRIKE_THRU_TEXT_FLAG); } return convertView; }
额外优化建议
你的Activity代码里有一行可以简化:
sites.set(position, selectedSite);
这行完全多余——selectedSite就是从sites列表里拿到的引用对象,你修改它的isBarred属性后,列表里的对象已经同步更新了,不需要再重新set回去,删掉这行不影响功能。
内容的提问来源于stack exchange,提问作者colisage app
相关产品推荐
相关产品推荐

