ListView单个项高亮异常求助:多项出现加粗效果
嘿,这个坑我踩过好多次!你遇到的问题根源在于ListView的View复用机制——当列表滚动时,已经滑出屏幕的Item View(也就是convertView)会被重新拿来给新进入屏幕的Item使用。如果你的代码只在position == selection时设置高亮/加粗,却没有在非选中状态下重置样式,那些被复用的View就会带着之前的高亮状态“上岗”,导致看起来多个Item被选中了。
问题拆解
你说日志里显示加粗/背景设置只被调用一次,但实际多个Item出现加粗?其实是因为复用的View保留了之前的设置,而日志只记录了第一次设置的情况,后续复用的时候并没有重新执行重置样式的代码。背景色没问题可能是因为你在布局里给Item设置了默认背景,而加粗是动态设置的,没有默认重置的步骤。
解决方案:在getView中同时处理选中和未选中状态
不管Item是否被选中,都要明确设置它的样式——选中时用高亮样式,未选中时恢复默认样式,不能只处理选中的情况。
举个代码例子,假设你用的是ArrayAdapter,重写getView应该这样写:
listView.setAdapter(new ArrayAdapter<String>(context, android.R.layout.simple_list_item_1, dataList) { @Override public View getView(int position, View convertView, ViewGroup parent) { TextView textView = (TextView) super.getView(position, convertView, parent); // 关键:同时处理两种状态 if (position == selection) { // 选中状态:加粗+背景色 textView.setTypeface(null, Typeface.BOLD); textView.setBackgroundColor(Color.parseColor("#FFDDDD")); } else { // 未选中状态:重置为默认样式 textView.setTypeface(null, Typeface.NORMAL); textView.setBackgroundColor(Color.TRANSPARENT); // 或者用布局里的默认背景色 } return textView; } });
额外优化:使用ViewHolder模式(可选但推荐)
如果你的Item布局比较复杂,用ViewHolder可以提升性能,同时确保每个View的状态都被正确设置:
listView.setAdapter(new ArrayAdapter<String>(context, R.layout.your_custom_item_layout, dataList) { @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder; if (convertView == null) { convertView = LayoutInflater.from(context).inflate(R.layout.your_custom_item_layout, parent, false); holder = new ViewHolder(); holder.textView = convertView.findViewById(R.id.item_text); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } // 设置文本内容 holder.textView.setText(dataList.get(position)); // 设置样式 if (position == selection) { holder.textView.setTypeface(null, Typeface.BOLD); holder.textView.setBackgroundColor(Color.parseColor("#FFDDDD")); } else { holder.textView.setTypeface(null, Typeface.NORMAL); holder.textView.setBackgroundColor(Color.TRANSPARENT); } return convertView; } class ViewHolder { TextView textView; } });
为什么之前的代码不行?
你之前只在position == selection时设置样式,没有处理else的情况。比如,当Item 0被选中并加粗,然后它滑出屏幕,这个View被复用给Item 8,此时position == selection不成立,但你没有把加粗改回正常,所以Item 8也会显示加粗——这就是你看到多个Item被高亮的原因。
只要确保每次getView时,不管是否选中,都明确设置对应的样式,就能解决这个问题啦!
内容的提问来源于stack exchange,提问作者Joseph Rand

