RecyclerView点击新项后重置旧选中项的实现问题
解决RecyclerView单选时重置前选中项的问题
要实现点击新条目时自动重置之前选中项的状态,核心是记录选中位置,并在onBindViewHolder中统一根据选中状态设置UI样式,而不是只在点击时修改当前项。以下是修改后的完整代码:
public class DateAdapter extends RecyclerView.Adapter<DateAdapter.VH> { private List<DateModel> driverListModelList; private ClickListener clickListener; private int selectedPosition = -1; // 记录选中位置,-1表示无选中项 public DateAdapter(List<DateModel> driverListModelList, ClickListener clickListener) { this.driverListModelList = driverListModelList; this.clickListener = clickListener; } @NonNull @Override public DateAdapter.VH onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.date_item, parent, false); return new DateAdapter.VH(v); } @Override public void onBindViewHolder(@NonNull DateAdapter.VH holder, int position) { DateModel model = driverListModelList.get(position); holder.setData(model.getDay(), model.getMonth(), model.getDate()); // 根据选中状态设置UI样式 if (position == selectedPosition) { // 选中状态 holder.itemView.setBackground(ContextCompat.getDrawable(holder.itemView.getContext(), R.drawable.day_bar_item2)); holder.day.setTextColor(Color.WHITE); holder.month.setTextColor(Color.WHITE); holder.date.setTextColor(Color.WHITE); } else { // 初始状态,替换成你自己的默认背景和文字颜色 holder.itemView.setBackground(ContextCompat.getDrawable(holder.itemView.getContext(), R.drawable.day_bar_item)); holder.day.setTextColor(Color.BLACK); holder.month.setTextColor(Color.BLACK); holder.date.setTextColor(Color.BLACK); } // 条目点击事件 holder.itemView.setOnClickListener(view -> { int oldPosition = selectedPosition; selectedPosition = holder.getBindingAdapterPosition(); // 获取当前正确的位置(避免ViewHolder复用问题) // 刷新旧选中项和新选中项 if (oldPosition != -1) { notifyItemChanged(oldPosition); } notifyItemChanged(selectedPosition); // 回调外部点击事件 clickListener.onItemClicked(selectedPosition); }); } @Override public int getItemCount() { return driverListModelList.size(); } class VH extends RecyclerView.ViewHolder implements View.OnClickListener { private TextView day; private TextView month; private TextView date; @SuppressLint("ResourceAsColor") public VH(@NonNull View itemView) { super(itemView); day = itemView.findViewById(R.id.dayTxt); month = itemView.findViewById(R.id.txtMonth); date = itemView.findViewById(R.id.txtDate); itemView.setOnClickListener(this); } private void setData(final String day, final String month, final String date) { this.day.setText(day); this.month.setText(month); this.date.setText(date); } @Override public void onClick(View view) { clickListener.onItemClicked(getAdapterPosition()); } } }
关键改动说明:
- 添加选中位置变量:用
selectedPosition记录当前选中的条目位置,初始值设为-1表示无选中项。 - 在
onBindViewHolder中统一处理样式:每次绑定条目时,根据当前位置是否为选中位置,分别设置选中/初始状态的UI。这解决了ViewHolder复用导致的状态错乱问题。 - 精准刷新条目:点击新条目时,先保存旧选中位置,更新新位置后,仅刷新旧选中项和新选中项,比
notifyDataSetChanged更高效,也能保证状态正确重置。 - 使用
getBindingAdapterPosition()获取位置:避免ViewHolder复用导致的位置错误,确保获取到当前条目的真实位置。
你之前调用recyclerView.invalidate()和notifyDataSetChanged()无效的原因是:没有在onBindViewHolder中根据选中状态重置UI,即使刷新所有条目,复用的ViewHolder仍会保持之前修改的样式,无法回到初始状态。
内容的提问来源于stack exchange,提问作者Aaraf Rao
相关产品推荐
相关产品推荐

