在回收站视图中滚动时,它向选定的复选框列表添加了一些其他值
Posted
技术标签:
【中文标题】在回收站视图中滚动时,它向选定的复选框列表添加了一些其他值【英文标题】:while scrolling in recycler view it added some other values to the selected list of checkboxes 【发布时间】:2020-11-06 05:22:20 【问题描述】:在这里你可以看到我有一个 plist,当用户点击 select all
按钮时,我在其中获取选定的复选框。
这是当我显示数据列表时。只有那些复选框的数据在屏幕上可见,当我向下滚动时,剩余的复选框被选中,当我再滚动一段时间时,它会重复选中复选框的另一个值
Adapter.java
public class AttendanceRegisterAdapter extends RecyclerView.Adapter<AttendanceRegisterAdapter.AttendanceViewHolder>
Context context;
private ArrayList<Student> student;
private boolean isSelectedAll;
private ArrayList<String> plist = new ArrayList<>();
public AttendanceRegisterAdapter(Context context, ArrayList<Student> student)
this.context = context;
this.student = student;
@NonNull
@Override
public AttendanceViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType)
LayoutInflater inflater = LayoutInflater.from(context);
View view = inflater.inflate(R.layout.template_card_student, parent, false);
return new AttendanceViewHolder(view);
public void selectAll()
isSelectedAll = true;
notifyDataSetChanged();
public void unSelectAll()
isSelectedAll = false;
notifyDataSetChanged();
@Override
public void onBindViewHolder(@NonNull AttendanceViewHolder holder, int position)
final Student selectedList = student.get(position);
holder.cbAttendance.setSelected(selectedList.getSelected());
holder.cbAttendance.setTag(position);
if (isSelectedAll)
selectedList.setSelected(true);
plist.add(student.get(position).getStudentID());
else
selectedList.setSelected(false);
plist.remove(student.get(position).getStudentID());
holder.cbAttendance.setChecked(selectedList.getSelected());
@Override
public int getItemCount()
return student.size();
class AttendanceViewHolder extends RecyclerView.ViewHolder
CardView cvStudentCard;
ImageView imgStudentPicture;
TextView txtStudentName;
CheckBox cbAttendance;
public AttendanceViewHolder(@NonNull View itemView)
super(itemView);
cvStudentCard = itemView.findViewById(R.id.card_student_view);
imgStudentPicture = itemView.findViewById(R.id.img_student_picture);
txtStudentName = itemView.findViewById(R.id.tv_card_title);
cbAttendance = itemView.findViewById(R.id.cb_attendance);
【问题讨论】:
您好,欢迎来到 SO。这里的实际问题是什么? 【参考方案1】:您在 BindViewHolder 中添加 StudentId 而不检查 plist 每次调用 BindViewHolder 时可能会添加重复值。
public class AttendanceRegisterAdapter extends RecyclerView.Adapter<AttendanceRegisterAdapter.AttendanceViewHolder>
Context context;
private ArrayList<Student> student;
private boolean isSelectedAll;
private ArrayList<String> plist = new ArrayList<>();
public AttendanceRegisterAdapter(Context context, ArrayList<Student> student)
this.context = context;
this.student = student;
@NonNull
@Override
public AttendanceViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType)
LayoutInflater inflater = LayoutInflater.from(context);
View view = inflater.inflate(R.layout.template_card_student, parent, false);
return new AttendanceViewHolder(view);
public void selectAll()
isSelectedAll = true;
notifyDataSetChanged();
public void unSelectAll()
isSelectedAll = false;
notifyDataSetChanged();
public Boolean checkElementExist(String element)
return plist.contains(element);
public void selectLeftOver(int nextPosition)
for (int i = nextPosition; nextPosition > getItemCount(); i++)
if (!checkElementExist(student.get(i).getStudentID()))
plist.add(student.get(i).getStudentID());
@Override
public void onBindViewHolder(@NonNull AttendanceViewHolder holder, int position)
final Student selectedList = student.get(position);
holder.cbAttendance.setSelected(selectedList.getSelected());
holder.cbAttendance.setTag(position);
if (isSelectedAll)
selectedList.setSelected(true);
if (!checkElementExist(student.get(position).getStudentID()))
plist.add(student.get(position).getStudentID());
selectLeftOver(position + 1);
else
selectedList.setSelected(false);
if (!checkElementExist(student.get(position).getStudentID()))
plist.remove(student.get(position).getStudentID());
holder.cbAttendance.setChecked(selectedList.getSelected());
@Override
public int getItemCount()
return student.size();
class AttendanceViewHolder extends RecyclerView.ViewHolder
CardView cvStudentCard;
ImageView imgStudentPicture;
TextView txtStudentName;
CheckBox cbAttendance;
public AttendanceViewHolder(@NonNull View itemView)
super(itemView);
cvStudentCard = itemView.findViewById(R.id.card_student_view);
imgStudentPicture = itemView.findViewById(R.id.img_student_picture);
txtStudentName = itemView.findViewById(R.id.tv_card_title);
cbAttendance = itemView.findViewById(R.id.cb_attendance);
【讨论】:
感谢此解决方案有效,但另一个问题是它仅添加了屏幕上可见的复选框的值。就像我有 20 个复选框和 2 个按钮。一个用于显示已选,一个用于全选。如果用户按下全选按钮,那么它只会添加 15 个复选框,当我向下滚动时,这些复选框在屏幕上可见,当剩余的复选框可见时,下次它会显示另外 5 个复选框值 问题在于 BindViewHolder。此方法仅执行 recyclerView 正在获取其列表项的数据以显示(可见)。在您的情况下,如果 15 个复选框在不滚动的情况下可见,则意味着只有 15 次 BindViewHolder 被调用和执行。当您向下滚动以查看剩余的 5 个项目时,比 BindViewHolder 再调用 5 次。所以,这就是问题所在。我已经编辑了我的代码来修复这个尝试..以上是关于在回收站视图中滚动时,它向选定的复选框列表添加了一些其他值的主要内容,如果未能解决你的问题,请参考以下文章
在顶部添加新项目后,回收器视图未滚动到顶部,因为尚未发生对列表适配器的更改