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

如何实现RecyclerView列表项的单选功能?

RecyclerView 单选列表项优化实现方案

要实现RecyclerView同一时间仅选中一个列表项,点击时切换带边框背景的需求,最规范高效的方式是在适配器中统一维护选中状态,结合onBindViewHolder处理视图样式,避免只修改单个视图导致的状态不一致问题。具体实现步骤如下:


1. 添加选中状态变量

在适配器类中新增一个变量,记录当前选中的列表项位置:

public class LanguageListAdapter extends RecyclerView.Adapter<LanguageListAdapter.ViewHolder>{
    private List<String> languages;
    private LayoutInflater inflater;
    private ItemClickListener itemClickListener; // 修复类型匹配问题
    private int selectedPosition = -1; // -1表示初始无选中项

    // 构造方法不变...

2. 在onBindViewHolder中统一设置背景

修改onBindViewHolder,根据当前位置是否为选中位置,切换对应的背景样式:

@Override
public void onBindViewHolder(ViewHolder holder, int position) {
    String language = languages.get(position);
    char langIconChar = language.charAt(0);
    holder.txtView1.setText(language);
    holder.langicon.setText(langIconChar + "");
    
    // 根据选中状态设置背景
    if (position == selectedPosition) {
        holder.itemView.setBackgroundResource(R.drawable.language_rect_outlined);
    } else {
        holder.itemView.setBackgroundResource(R.drawable.normal_background); // 替换为你的普通背景资源
    }
}

3. 处理点击事件,更新选中状态

调整ViewHolder中的onClick方法,更新选中位置并精准刷新受影响的视图(避免全量刷新提升性能):

@Override
public void onClick(View view) {
    int itemPosition = getAdapterPosition();
    if (itemPosition == RecyclerView.NO_POSITION) return; // 防止无效点击
    
    String item = languages.get(itemPosition);
    Context context = view.getContext();

    // 保存语言设置的逻辑保留
    SharedPreferences AppLanguage = context.getSharedPreferences("AppLanguage", Context.MODE_PRIVATE);
    SharedPreferences.Editor editor = AppLanguage.edit();
    editor.putString("language", item.toLowerCase());
    editor.apply();
    
    // 更新选中位置并刷新视图
    int previousSelected = selectedPosition;
    selectedPosition = itemPosition;
    // 刷新之前选中的项(如果存在)
    if (previousSelected != -1) {
        notifyItemChanged(previousSelected);
    }
    // 刷新当前选中的项
    notifyItemChanged(selectedPosition);
    
    // 回调外部点击事件(如果需要)
    if (itemClickListener != null) {
        itemClickListener.onItemClick(view, itemPosition);
    }
}

4. 修复适配器其他细节问题

  • 布局填充时不要传null,确保视图继承父布局的LayoutParams:
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    View view = inflater.inflate(R.layout.widget_languagelist, parent, false);
    return new ViewHolder(view);
}
  • 修正setClickListener的类型匹配问题:
void setClickListener(ItemClickListener itemClickListener) {
    this.itemClickListener = itemClickListener;
}

修改后的完整适配器代码

public class LanguageListAdapter extends RecyclerView.Adapter<LanguageListAdapter.ViewHolder>{

    private List<String> languages;
    private LayoutInflater inflater;
    private ItemClickListener itemClickListener;
    private int selectedPosition = -1;

    LanguageListAdapter(Context context, List<String> languages1) {
        this.inflater = LayoutInflater.from(context);
        this.languages = languages1;
    }

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = inflater.inflate(R.layout.widget_languagelist, parent, false);
        return new ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        String language = languages.get(position);
        char langIconChar = language.charAt(0);
        holder.txtView1.setText(language);
        holder.langicon.setText(langIconChar + "");
        
        // 设置选中/未选中背景
        if (position == selectedPosition) {
            holder.itemView.setBackgroundResource(R.drawable.language_rect_outlined);
        } else {
            holder.itemView.setBackgroundResource(R.drawable.normal_background);
        }
    }

    @Override
    public int getItemCount() {
        return languages.size();
    }

    public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{

        TextView txtView1,langicon;
        ConstraintLayout layout;

        ViewHolder(View itemView) {
            super(itemView);
            txtView1 = itemView.findViewById(R.id.languagename);
            langicon = itemView.findViewById(R.id.langicon);
            layout = itemView.findViewById(R.id.itemLayout);
            itemView.setOnClickListener(this);
        }

        @Override
        public void onClick(View view) {
            int itemPosition = getAdapterPosition();
            if (itemPosition == RecyclerView.NO_POSITION) return;
            
            String item = languages.get(itemPosition);
            Context context = view.getContext();

            // 保存语言设置
            SharedPreferences AppLanguage = context.getSharedPreferences("AppLanguage", Context.MODE_PRIVATE);
            SharedPreferences.Editor editor = AppLanguage.edit();
            editor.putString("language", item.toLowerCase());
            editor.apply();
            
            // 更新选中状态并刷新视图
            int previousSelected = selectedPosition;
            selectedPosition = itemPosition;
            if (previousSelected != -1) {
                notifyItemChanged(previousSelected);
            }
            notifyItemChanged(selectedPosition);
            
            // 回调外部点击事件
            if (itemClickListener != null) {
                itemClickListener.onItemClick(view, itemPosition);
            }
        }
    }

    String getItem(int id) {
        return languages.get(id);
    }

    void setClickListener(ItemClickListener itemClickListener) {
        this.itemClickListener = itemClickListener;
    }

    public interface ItemClickListener {
        void onItemClick(View view, int position);
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 23:15:43