Java 添加notifyDataSetChanged()后检测到不一致错误

Java 添加notifyDataSetChanged()后检测到不一致错误,java,android,android-recyclerview,notifydatasetchanged,Java,Android,Android Recyclerview,Notifydatasetchanged,我正在做一个活动日志,我有一个问题,我不能向下滚动一个不一致的错误不断弹出。我也添加了notifyDataSetChanged方法,但我仍然无法修复错误 这是我得到的错误 java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid item position 7(offset:7).state:11 android.support.v7.widget.RecyclerView{edb17ac 这是我的适配器代码 p

我正在做一个活动日志,我有一个问题,我不能向下滚动一个不一致的错误不断弹出。我也添加了notifyDataSetChanged方法,但我仍然无法修复错误

这是我得到的错误

java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid item position 7(offset:7).state:11 android.support.v7.widget.RecyclerView{edb17ac 
这是我的适配器代码

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder>{

private List<ListItem> listItems;
private Context context;

public MyAdapter(List<ListItem> listItems, Context context) {
    this.listItems = listItems;
    this.context = context;
}

public MyAdapter(Context applicationContext, List<ListItem> listItems) {
}

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

@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {

    for(int i=0;i<listItems.size(); i++){
        if (listItems.get(position).getHead().equals("Time")){
            listItems.remove(listItems.get(position));
        }
    }
    ListItem listItem = listItems.get(position);
    String key = listItem.getHead();
    if (key.equals("LockTime")) {
        holder.textViewHead.setText(listItem.getTime());
        holder.textViewDesc.setText(listItem.getDesc());
        holder.layout.setBackground(ContextCompat.getDrawable(context, R.drawable.red_gradient));
        holder.image1.setImageResource(R.drawable.lockwhite);
        holder.image2.setImageResource(R.drawable.lockwhite);
    } else if (key.equals("UnlockTime")) {
        holder.textViewHead.setText(listItem.getTime());
        holder.textViewDesc.setText(listItem.getDesc());
        holder.layout.setBackground(ContextCompat.getDrawable(context, R.drawable.green_gradient));
        holder.image1.setImageResource(R.drawable.unlockwhite);
        holder.image2.setImageResource(R.drawable.unlockwhite);
    }
}

@Override
public int getItemCount() {
    return listItems.size();
}
public class ViewHolder extends RecyclerView.ViewHolder{

    public TextView textViewHead;
    public TextView textViewDesc;
    public RelativeLayout layout;
    public ImageView image1;
    public ImageView image2;


    public ViewHolder(View itemView) {
        super(itemView);

        textViewHead = (TextView) itemView.findViewById(R.id.textViewHead);
        textViewDesc = (TextView) itemView.findViewById(R.id.textViewDesc);
        layout= (RelativeLayout) itemView.findViewById(R.id.relativelayout);
        image1 = itemView.findViewById(R.id.padlock1);
        image2 = itemView.findViewById(R.id.padlock2);
    }
  }



}
公共类MyAdapter扩展了RecyclerView.Adapter{ 私人物品清单; 私人语境; 公共MyAdapter(列表项、上下文){ this.listItems=listItems; this.context=上下文; } 公共MyAdapter(上下文应用程序上下文,列表项){ } @非空 @凌驾 public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent,int viewType){ 视图v=LayoutInflater.from(parent.getContext()) .充气(R.layout.list_项,父项,假); 返回新的视图持有者(v); } @凌驾 public void onBindViewHolder(@NonNull ViewHolder,int位置){
对于(int i=0;i我希望这对您有用

您设置了两次适配器。请删除下面的行

recyclerView.setAdapter(new MyAdapter(getApplicationContext(),listItems));
adapter.notifyDataSetChanged();

刷新时使用SwipRefreshLayout时禁用recyclerview滚动。一次滚动和更新数据会导致不一致错误。

只有在适配器中存在多次添加、删除或重新排列时,才需要notifyDataSetChanged()。调用setAdapter时,没有必要调用notifyDataSetChanged().

绑定viewholder时不应从列表中删除项目,因为您更改了位置,需要重新创建RecyclerView。 在构造函数中或适配器以外的任何位置删除它们

public MyAdapter(List<ListItem> listItems, Context context) {
    for(int i=0;i<listItems.size(); i++){
        if (listItems.get(position).getHead().equals("Time")){
            listItems.remove(listItems.get(position));
        }
     }
     this.listItems = listItems;
     this.context = context;
}
公共MyAdapter(列表项、上下文){
对于(int i=0;i在我看来,适配器没有意义。
onBindViewHolder()
方法每次都会在您的recyclerview项绑定时调用。它意味着所有操作,当您在适配器中添加/删除/更改项时,以及当您滚动视图时。因此,不建议为()调用
在绑定视图时,无条件地每次循环。我希望从列表中删除一些值,因此我将其放入for循环中,并删除标题为timewhy in adapter的项。如果要自动执行此操作,请在将数据传递给adapter之前,在活动中执行此操作。解决方案添加了一个选项,据说将for循环放在构造函数中而不是onBindViewHolder中。非常感谢您的反馈:)它起作用了,我现在明白了为什么遍历onBindViewHolder是一种不好的做法。非常感谢您的帮助!:)
public MyAdapter(List<ListItem> listItems, Context context) {
    for(int i=0;i<listItems.size(); i++){
        if (listItems.get(position).getHead().equals("Time")){
            listItems.remove(listItems.get(position));
        }
     }
     this.listItems = listItems;
     this.context = context;
}