【发布时间】:2018-01-06 23:10:44
【问题描述】:
我想实现一个简单的自定义多选 RecyclerView。 我的问题是当我选择屏幕中的第一个 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 个条目也检查了studensToBeRemoved.add(studentListItemList.get(pos).getId());,因为实际上从未调用过第 10 个条目。 (
Toast.makeText(mContext,String.valueOf(pos)+ ": "+stringBuilder.toString(),Toast.LENGTH_LONG).show();
in the end of onLongClickListener shows only the correct values every time ( e.g. when is select the first entry it shows "1: 1") although entry 10 is also selected).最后,如果我选择条目 10,则会发生相反的情况(条目 1 也被选中)。 任何想法出了什么问题?如果需要,我还可以提供一些屏幕截图或更多详细信息。
谢谢!
【问题讨论】:
标签: java android android-recyclerview