如何实现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
相关产品推荐
相关产品推荐

