web-dev-qa-db-fra.com

Impossible d'appeler cette méthode lorsque RecyclerView est en train de calculer une mise en page ou de faire défiler le texte lorsque vous essayez de supprimer un élément de recyclerview

J'essaie de retirer mon article de recyclage, mais j'obtiens toujours une erreur 

Java.lang.IllegalStateException: Impossible d'appeler cette méthode tant que RecyclerView est en train de calculer une mise en page ou de faire défiler

j'utilise notifier datasetchanged, puis-je résoudre ce problème?

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);

        }
    }
}
6
Denny Kurniawan

La réponse ci-dessous a fonctionné pour moi 

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

Vous utilisez votre instance RecyclerView et, dans la méthode post, un nouveau fichier Runnable ajouté à la file d'attente des messages. Le runnable sera exécuté sur le thread d'interface utilisateur. Il s’agit d’une limite imposée à Android pour accéder au thread UI à partir de l’arrière-plan (par exemple, dans une méthode qui sera exécutée dans un thread en arrière-plan) ..__ pour plus vous l'exécutez sur le fil UI si vous aviez besoin.

Pour plus, vous pouvez le lancer sur le fil UI, si vous en aviez besoin 

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

Je vous donne une autre idée pour résoudre votre problème. Je pense que cela pourrait être mieux. L'idée est que nous ne supprimons pas les données non valides dans onBindViewHolder, nous les supprimerons avant 

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()));

}
1
Linh

Ceci est utile lorsque vous cochez la case Tout en cliquant sur la case en haut de recyclerview.

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