Multiselection RecyclerView也选择其他项目

时间:2018-01-05 21:01:35

标签: java android android-recyclerview

我想实现一个简单的自定义多选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();
在onLongClickListener的末尾每次只显示正确的值(例如,当选择显示“1:1”的第一个条目时),尽管也选择了条目10)。最后,如果我选择条目10,则相反的情况发生(条目1也被选中)。 任何想法出了什么问题?如果需要,我还可以提供一些截图或更多细节。

谢谢!

1 个答案:

答案 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)方法。