1

Ok so it is a bit complicated, I have a custom RecyclerView Adapter and in the OnBindViewHolder method I would like to remove the current item from the recyclerview depending on some different variables but when I remove the item from the ArrayList and call notifyDataSetChanged(); I get : java.lang.IllegalStateException: Cannot call this method while RecyclerView is computing a layout or scrolling.

How can I remove the item from the RecyclerView in the onBindViewHolder ? , I do not want to do it before setting the adapter because each item in the recyclerview has a sublist and I want to remove the item if the sublist is empty. Thanks for any ideas and sorry for bad english.

Amr El Aswar
  • 3,395
  • 3
  • 23
  • 36

2 Answers2

3

Please follow the method used below as shown in this answer.

private List<DetectedIssue> issues = new ArrayList<DetectedIssue>();

@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
// - get element from your dataset at this position
// - replace the contents of the view with that element

    holder.button.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            try {
                issues.remove(position);
                notifyItemRemoved(position);
                //this line below gives you the animation and also updates the
                //list items after the deleted item
                notifyItemRangeChanged(position, getItemCount());

            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    });
}

 @Override
 public int getItemCount() {
    return issues.size();
 }

PS: As can be seen from the documentation it is bad practice to use notifyDataSetChanged() if only an item is added, moved or removed as unnecessary processes are run.

This event does not specify what about the data set has changed, forcing any observers to assume that all existing items and structure may no longer be valid. LayoutManagers will be forced to fully rebind and relayout all visible views.

If you want the underlying arraylist in some activity be changed then you will have to use an interface to communicate with the activity to change the arraylist.

Community
  • 1
  • 1
suku
  • 10,507
  • 16
  • 75
  • 120
0

I know its a bit late (4 years, heh) but I'm in the same solution. As the error states it is actually impossible to call methods such as adapter.notifyItemRemoved(position); or notifyItemRangeChanged(position, getItemCount()); and even the more intensive notifyDataSetChanged(); from within the onBindViewHolder method unless it is within an onClickListener whereby it will be called after the layout is built and not during the build. A simple workaround for me was to call datalist.remove(position); so if the layout is rebuilt the view is omitted, then simply call holder.itemView.setVisibility(View.GONE);. It's not as clean, but it gets the job done for views you wish to hide.