我想实现一个简单的自定义多选ReclerView。 我的问题是当我在屏幕上选择第一个CardView元素时,也选择了第十张卡片(当我选择第二张卡片时,选择了第十一张卡片等)。我尝试过很多不同的东西,例如使用`notifyItemChanged(pos),但我总是遇到同样的错误。
以下是我的自定义类的代码。
public class StudentRecyclerAdapter extends RecyclerView.Adapter<StudentRecyclerAdapter.CustomViewHolder> {
private List<Student> studentListItemList;
private Context mContext;
private Students students;
private Set<Integer> studensToBeRemoved;
private List<Boolean> selected;
public StudentRecyclerAdapter(Context context, List<Student> studentListItemList, Students students) {
this.studentListItemList = studentListItemList;
this.mContext = context;
this.studensToBeRemoved = new HashSet<>();
this.students = students;
selected= new ArrayList<>();
for(int i=0;i<studentListItemList.size();i++)
selected.add(false);
}
View.OnClickListener clickListener = new View.OnClickListener() {
@Override
public void onClick(View view) {
CustomViewHolder holder = (CustomViewHolder) view.getTag();
int position = holder.getAdapterPosition();
Student studentListItem = studentListItemList.get(position);
Bundle extras = new Bundle();
extras.putInt("id", studentListItem.getId());
extras.putString("name", studentListItem.getName());
extras.putString("surname", studentListItem.getSurname());
extras.putLong("date", studentListItem.getLongBirthday());
extras.putString("photo", studentListItem.getImage());
Intent intent = new Intent(mContext, ProfileStudent.class);
intent.putExtras(extras);
mContext.startActivity(intent);
}
};
View.OnLongClickListener longClickListener = view -> {
final CustomViewHolder holder = (CustomViewHolder) view.getTag();
int pos = holder.getAdapterPosition();
if (!selected.get(pos)) {
holder.stud_card_view.setCardBackgroundColor(Color.GREEN);
studensToBeRemoved.add(studentListItemList.get(pos).getId());
selected.set(pos,true);
} else {
holder.stud_card_view.setCardBackgroundColor(Color.WHITE);
studensToBeRemoved.remove(studentListItemList.get(pos).getId());
selected.set(pos,false);
}
if (studensToBeRemoved.size() > 0)
students.onMethodCallback(true);
else
students.onMethodCallback(false);
StringBuilder stringBuilder= new StringBuilder();
for(Integer integer : studensToBeRemoved)
stringBuilder.append(integer).append(", ");
Toast.makeText(mContext,String.valueOf(pos)+ ": "+stringBuilder.toString(),Toast.LENGTH_LONG).show();
return true;
};
@Override
public CustomViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.student_list_row, null);
RecyclerView.LayoutParams lp = new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
view.setLayoutParams(lp);
CustomViewHolder viewHolder = new CustomViewHolder(view);
return viewHolder;
}
@Override
public void onBindViewHolder(CustomViewHolder customViewHolder, int i) {
}
@Override
public void onBindViewHolder(CustomViewHolder customViewHolder, int i, List<Object> payload) {
if (payload.size() == 1) {
if ((boolean) payload.get(0)) {
customViewHolder.stud_card_view.setCardBackgroundColor(Color.GREEN);
studensToBeRemoved.add(studentListItemList.get(i).getId());
} else {
customViewHolder.stud_card_view.setCardBackgroundColor(Color.WHITE);
studensToBeRemoved.remove(studentListItemList.get(i).getId());
}
if (studensToBeRemoved.size() > 0)
students.onMethodCallback(true);
else
students.onMethodCallback(false);
} else {
Student studentListItem = studentListItemList.get(i);
Picasso.with(mContext).load(studentListItem.getImage())
.error(R.drawable.placeholder)
.placeholder(R.drawable.placeholder)
.into(customViewHolder.imageView);
customViewHolder.textView.setText(studentListItem.getName() + " " + studentListItem.getSurname());
customViewHolder.stud_card_view.setTag(customViewHolder);
customViewHolder.stud_card_view.setOnClickListener(clickListener);
customViewHolder.stud_card_view.setOnLongClickListener(longClickListener);
}
}
@Override
public int getItemCount() {
return (null != studentListItemList ? studentListItemList.size() : 0);
}
public void setFilter(ArrayList<Student> newList) {
studentListItemList = new ArrayList<>();
studentListItemList.addAll(newList);
notifyDataSetChanged();
}
public Set<Integer> getStudensToBeRemoved() {
return studensToBeRemoved;
}
public class CustomViewHolder extends RecyclerView.ViewHolder {
protected ImageView imageView;
protected TextView textView;
protected CardView stud_card_view;
public CustomViewHolder(View view) {
super(view);
this.imageView = view.findViewById(R.id.stud_list_pic);
this.textView = view.findViewById(R.id.stud_list_name);
this.stud_card_view = view.findViewById(R.id.stud_card_view);
}
}
}
PS。我有有效负载检查是因为我还实现了一个selectAll()
方法(我从片段主机中调用RecyclerView),该方法使用notifyItemRangeChanged()
正常工作。
最后,即使是第10个条目也被检查,第10个条目的studensToBeRemoved.add(studentListItemList.get(pos).getId());
实际上从未被调用。 (
Toast.makeText(mContext,String.valueOf(pos)+ ": "+stringBuilder.toString(),Toast.LENGTH_LONG).show();
谢谢!
答案 0 :(得分:0)
我设法解决了这个问题。所以这里是正确的代码,以防有人想要实现一个多选的简单RecyclerView。我希望它有所帮助。
public class StudentRecyclerAdapter extends RecyclerView.Adapter<StudentRecyclerAdapter.CustomViewHolder> {
private List<Student> studentListItemList;
private Context mContext;
private StudentsFragment students;
private Set<Integer> studensToBeRemoved;
private List<Boolean> selected;
private View.OnClickListener clickListener = new View.OnClickListener() {
@Override
public void onClick(View view) {
CustomViewHolder holder = (CustomViewHolder) view.getTag();
int pos = holder.getAdapterPosition();
if (studensToBeRemoved.size() == 0) {
Student studentListItem = studentListItemList.get(pos);
Bundle extras = new Bundle();
extras.putInt("id", studentListItem.getId());
extras.putString("name", studentListItem.getName());
extras.putString("surname", studentListItem.getSurname());
extras.putLong("date", studentListItem.getLongBirthday());
extras.putString("photo", studentListItem.getImage());
Intent intent = new Intent(mContext, ProfileStudent.class);
intent.putExtras(extras);
mContext.startActivity(intent);
} else {
if (!selected.get(pos)) {
holder.stud_card_view.setCardBackgroundColor(Color.GREEN);
studensToBeRemoved.add(studentListItemList.get(pos).getId());
selected.set(pos, true);
} else {
holder.stud_card_view.setCardBackgroundColor(Color.WHITE);
studensToBeRemoved.remove(studentListItemList.get(pos).getId());
selected.set(pos, false);
}
if (studensToBeRemoved.size() > 0)
students.onMethodCallback(true);
else
students.onMethodCallback(false);
}
}
};
private View.OnLongClickListener longClickListener = view -> {
final CustomViewHolder holder = (CustomViewHolder) view.getTag();
int pos = holder.getAdapterPosition();
if (!selected.get(pos)) {
holder.stud_card_view.setCardBackgroundColor(Color.GREEN);
studensToBeRemoved.add(studentListItemList.get(pos).getId());
selected.set(pos, true);
} else {
holder.stud_card_view.setCardBackgroundColor(Color.WHITE);
studensToBeRemoved.remove(studentListItemList.get(pos).getId());
selected.set(pos, false);
}
if (studensToBeRemoved.size() > 0)
students.onMethodCallback(true);
else
students.onMethodCallback(false);
return true;
};
public StudentRecyclerAdapter(Context context, List<Student> studentListItemList, Students students) {
this.studentListItemList = studentListItemList;
this.mContext = context;
this.studensToBeRemoved = new HashSet<>();
this.students = students;
selected = new ArrayList<>();
for (int i = 0; i < studentListItemList.size(); i++)
selected.add(false);
}
@Override
public CustomViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.student_list_row, null);
RecyclerView.LayoutParams lp = new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
view.setLayoutParams(lp);
CustomViewHolder viewHolder = new CustomViewHolder(view);
return viewHolder;
}
@Override
public void onBindViewHolder(CustomViewHolder customViewHolder, int i) {
Student studentListItem = studentListItemList.get(i);
Picasso.with(mContext).load(studentListItem.getImage())
.error(R.drawable.placeholder)
.placeholder(R.drawable.placeholder)
.into(customViewHolder.imageView);
customViewHolder.textView.setText(studentListItem.getName() + " " + studentListItem.getSurname());
customViewHolder.stud_card_view.setTag(customViewHolder);
customViewHolder.edit_button.setTag(customViewHolder);
customViewHolder.stud_card_view.setOnClickListener(clickListener);
if (!selected.get(i))
customViewHolder.stud_card_view.setCardBackgroundColor(Color.WHITE);
else
customViewHolder.stud_card_view.setCardBackgroundColor(Color.GREEN);
customViewHolder.stud_card_view.setOnLongClickListener(longClickListener);
customViewHolder.stud_card_view.setOnClickListener(clickListener);
customViewHolder.edit_button.setOnClickListener(clickListener);
}
@Override
public int getItemCount() {
return (null != studentListItemList ? studentListItemList.size() : 0);
}
public void setFilter(ArrayList<Student> newList) {
studentListItemList = new ArrayList<>();
studentListItemList.addAll(newList);
notifyDataSetChanged();
}
public Set<Integer> getStudensToBeRemoved() {
return studensToBeRemoved;
}
public void setSelected(boolean b) {
if (b) {
for (int i = 0; i < selected.size(); i++) {
studensToBeRemoved.add(studentListItemList.get(i).getId());
selected.set(i, true);
}
students.onMethodCallback(true);
} else {
for (int i = 0; i < selected.size(); i++) {
selected.set(i, false);
studensToBeRemoved.remove(studentListItemList.get(i).getId());
}
students.onMethodCallback(false);
}
notifyItemRangeChanged(0, getItemCount());
}
public class CustomViewHolder extends RecyclerView.ViewHolder {
protected ImageView imageView;
protected TextView textView;
protected CardView stud_card_view;
protected ImageButton edit_button;
public CustomViewHolder(View view) {
super(view);
this.imageView = view.findViewById(R.id.stud_list_pic);
this.textView = view.findViewById(R.id.stud_list_name);
this.stud_card_view = view.findViewById(R.id.stud_card_view);
this.edit_button = view.findViewById(R.id.student_edit_btn);
edit_button.bringToFront();
}
}
}
students.onMethodCallback()
函数通知主机片段显示/隐藏删除按钮。要一次选择/取消选择所有元素,您只需调用setSelected(true/false)
方法。