【问题标题】:Multiselection RecyclerView selects other items alsoMultiselection RecyclerView 也选择其他项目
【发布时间】: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


    【解决方案1】:

    我设法修复它。所以这里是正确的代码,以防有人想要实现一个简单的多选 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) 方法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-10-19
      • 2019-08-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多