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

ListView单个项高亮异常求助:多项出现加粗效果

解决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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 08:48:53