当RecyclerView计算布局或滚动时尝试从recyclerview中删除项目时,无法调用此方法

时间:2017-04-05 04:30:36

标签: android android-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);

        }
    }
}

8 个答案:

答案 0 :(得分:30)

以下答案适合我

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

答案 1 :(得分:6)

要使用此方法,需要两种方法:

if (!rv.isComputingLayout && rv.scrollState == SCROLL_STATE_IDLE) {
   rv.adapter?.notifyDataSetChanged()
}

答案 2 :(得分:2)

当单击“回收站视图”中的顶部复选框时选中“全部”复选框时,这非常有用。

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

答案 3 :(得分:1)

我给你另一个解决问题的想法。我认为可能会更好 我们的想法是,我们不会删除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 :(得分:1)

如果您打算通知回避物品,请使用isComputingLayout方法:

if (!mRecyclerView.isComputingLayout()) 
{
 // add your code here
}

答案 5 :(得分:0)

在构造项目时,您将使用onBindViewHolder()方法通知项目更改。很可能您可以改善逻辑,以避免这种情况。

答案 6 :(得分:-1)

在Kotlin中像这样使用...

gridpercent = percent = wb.add_format(...)

协程是一个对象类

Coroutines.io {
  //add code which can run in background

  Coroutines.main {
      //add code which update UI
      notifyItemRangeChanged(position, count)
  }
}

}

答案 7 :(得分:-2)

我只是为此设置了一个延迟时间

        new Handler().postDelayed(() ->  notifyDataSetChanged(), 1000);