Невозможно вызвать этот метод, в то время как RecyclerView вычисляет макет или прокрутку при попытке удалить элемент из recyclerview

Я пытаюсь удалить свой элемент из recyclerview, но я всегда получаю ошибку

java.lang.IllegalStateException: не удается вызвать этот метод, в то время как RecyclerView вычисляет макет или прокрутку

Я использую notify datasetchanged, могу ли я решить это?

public class AdapterIntransit extends RecyclerView.Adapter<AdapterIntransit.ViewHolder> {
    private Context context;
    List<DataIntransit> data;

    public AdapterIntransit(Context context, List<DataIntransit> data) {
        this.context = context;
        this.data = data;
    }

    @Override
    public AdapterIntransit.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.cardintransit, parent, false);
        return new ViewHolder(itemView);
    }

    @Override
    public void onBindViewHolder(AdapterIntransit.ViewHolder holder, int position) {
        if (data.get(position).getJml1() - data.get(position).getJml2() <= 0) {
            data.remove(position);
            notifyItemRemoved(position);
            notifyItemRangeChanged(position, getItemCount());
            notifyDataSetChanged();
        } else {
            holder.kode.setText(data.get(position).getKode());
            holder.nama.setText(data.get(position).getNama());
            holder.jumlah.setText(String.valueOf(data.get(position).getJml1() - data.get(position).getJml2()));
        }
    }

    @Override
    public int getItemCount() {
        return data.size();
    }
    public class ViewHolder extends RecyclerView.ViewHolder{
        TextView kode, nama, jumlah;
        public ViewHolder(View itemView) {
            super(itemView);
            kode = (TextView)itemView.findViewById(R.id.kode);
            nama = (TextView)itemView.findViewById(R.id.nama);
            jumlah = (TextView)itemView.findViewById(R.id.jumlah);

        }
    }
}

Ответ 1

Ниже ответ работал для меня

dialeecyclerView.post(new Runnable()
            {
                @Override
                public void run() {
                myadapter.notifyDataSetChanged();
            }
            });

Вы используете свой экземпляр RecyclerView а внутри метода post новый Runnable добавляется в очередь сообщений. Runnable будет запущен в потоке пользовательского интерфейса. Это ограничение для Android для доступа к потоку UI из фона (например, внутри метода, который будет выполняться в фоновом потоке). для большего вы запускаете его в потоке UI если вам нужно.

Для большего вы можете запустить его в потоке UI, если вам нужно

 runOnUiThread(new Runnable(){
 public void run() {
      // UI code goes here
 }
 });

Ответ 2

Это полезно, когда установлен флажок "Все" при щелчке по верхнему флажку в представлении реселлера.

recyclerview.post(new Runnable()
{
     @Override
     public void run() {
         myadapter.notifyDataSetChanged();
     }
});

Ответ 3

Я даю вам еще одну идею для решения вашей проблемы. Я думаю, что это может быть лучше. Идея в том, что мы не удаляем недействительные данные внутри onBindViewHolder, мы удалим их раньше

public AdapterIntransit(Context context, List < DataIntransit > data) {
    this.context = context;
    this.data = removeInValidData(data);
}

private void removeInValidData(List < DataIntransit > data) {
    for (int position = 0, position < data.size(); position++) {
        if (data.get(position).getJml1() - data.get(position).getJml2() <= 0) {
            data.remove(position);
        }
    }
}

@Override
public void onBindViewHolder(AdapterIntransit.ViewHolder holder, int position) {
    holder.kode.setText(data.get(position).getKode());
    holder.nama.setText(data.get(position).getNama());
    holder.jumlah.setText(String.valueOf(data.get(position).getJml1() - data.get(position).getJml2()));

}

Ответ 4

Вы уведомляете об изменении элемента внутри onBindViewHolder(), когда ваш элемент находится в процессе конструирования. Скорее всего, вы можете просто улучшить свою логику, чтобы избежать этого.

Ответ 5

Не стоит писать эти логики в методе вашего адаптера onBindViewHolder().

Но если вам это действительно нужно, вы можете сделать что-то вроде этого:

new Handler().post(new Runnable() {
  @Override
  public void run() {
    // your code here. eg: notifyDataSetChanged()
  }
});