1. ホーム
  2. android

[解決済み] RecyclerViewからアイテムを削除しようとすると、RecyclerViewがレイアウトを計算している間、またはスクロールしている間は、このメソッドを呼び出すことができません。

2022-02-19 08:21:13

質問

リサイクルビューからアイテムを削除しようとしているのですが、いつもエラーが発生します。

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

        }
    }
}

解決方法は?

以下の回答は私にとって効果的でした。

これはまさに workaround を問題視しています。

この現象は、通常 notifyDataSetChanged() の上で background thread . そこで、notify を UI thread

recyclerView.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
 }
 });