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

Staggered Grid选中项显示异常问题求助

解决Staggered Grid滑动时选中状态错乱的问题

这个问题的核心原因是RecyclerView的ViewHolder复用机制——当你滑动列表时,离开屏幕的ViewHolder会被重新绑定到新的位置,而你之前只在点击时修改UI,没有在每次绑定的时候根据数据的选中状态重置UI,导致复用的ViewHolder带着旧的状态显示在新位置上,就出现了错乱。

下面是针对性的修复方案和代码修改:

1. 优化选中状态的存储方式

首先把原来的List<String> items改成Set<String>,因为选中的项应该是唯一的,Set的contains()和remove()操作效率更高,还能自动避免重复添加相同文本的项:

Set<String> selectedItems = new HashSet<>();

2. 在onBindViewHolder中强制同步UI与选中状态

每次绑定ViewHolder的时候,必须根据当前项是否被选中,设置对应的背景样式——这是解决复用错乱的关键!不能只在点击时修改UI,要确保每个ViewHolder在显示前都拿到正确的状态:

@Override
public void onBindViewHolder(final ViewHolder holder, final int position) {
    Log.d(TAG,"On Bind View Holder ");
    String currentText = jsonList.get(position);
    holder.textView.setText(currentText);
    
    // 核心:每次绑定都根据选中状态设置背景
    if (selectedItems.contains(currentText)) {
        // 选中状态的背景
        holder.textView.setBackgroundDrawable(
            holder.textView.getContext().getResources().getDrawable(R.drawable.round_button_interest)
        );
    } else {
        // 未选中状态的背景
        GradientDrawable shape = new GradientDrawable(
            GradientDrawable.Orientation.LEFT_RIGHT,
            new int[] {Color.parseColor("#FFc0c0c0"),Color.parseColor("#FF5E5E5E"),Color.parseColor("#FF000000")}
        );
        shape.setShape(GradientDrawable.RECTANGLE);
        shape.setCornerRadius(45);
        holder.textView.setBackgroundDrawable(shape);
    }
    
    holder.textView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Log.d(TAG,"On Click of Interest Calling "+position);
            if (selectedItems.contains(currentText)){
                Log.d(TAG,"Items Already Exist in List");
                selectedItems.remove(currentText);
                // 更新未选中状态的背景
                GradientDrawable shape = new GradientDrawable(
                    GradientDrawable.Orientation.LEFT_RIGHT,
                    new int[] {Color.parseColor("#FFc0c0c0"),Color.parseColor("#FF5E5E5E"),Color.parseColor("#FF000000")}
                );
                shape.setShape(GradientDrawable.RECTANGLE);
                shape.setCornerRadius(45);
                holder.textView.setBackgroundDrawable(shape);
            } else {
                selectedItems.add(currentText);
                // 更新选中状态的背景
                holder.textView.setBackgroundDrawable(
                    holder.textView.getContext().getResources().getDrawable(R.drawable.round_button_interest)
                );
                Log.d(TAG,"Items Size "+selectedItems.size());
            }
            // 可选:如果担心状态同步问题,可调用这个方法刷新当前项
            // notifyItemChanged(position);
        }
    });
}

3. 额外优化(可选)

如果你的列表中存在重复文本的项,用文本内容判断选中状态会出错(比如两个相同文本的项会被同时选中/取消)。这种情况下,建议创建一个实体类来存储每个项的信息,比如:

public class InterestItem {
    private String text;
    private boolean isSelected;
    
    // 构造方法、getter、setter
}

然后把List<String> jsonList改成List<InterestItem>,直接通过isSelected字段判断状态,这样就完全不会有重复文本的问题了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 07:11:59