简体   繁体   English

在 recyclerview 上检测到 IndexOutOfBoundException 不一致

[英]IndexOutOfBoundException Inconsistency detected on recyclerview

Hi I am trying to delete an item from recycler view but after successfully deleting when I am scrolling to bottom application is getting crashed and it is showing this error.嗨,我正在尝试从回收站视图中删除一个项目,但是当我滚动到底部时成功删除后,应用程序崩溃并显示此错误。 I tried to call我试着打电话

notifyItemRemoved(position);
notifyItemRangeInserted(position, tasklists.size());

but still its not fixed, I am not sure if I am calling these functions correctly.但它仍然没有修复,我不确定我是否正确调用了这些函数。

2020-05-09 22:09:21.305 10376-10376/com.helpinghandsorg.helpinghands E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.helpinghandsorg.helpinghands, PID: 10376
    java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid item position 10(offset:10).state:11 androidx.recyclerview.widget.RecyclerView{d7547e3 VFED..... ........ 0,0-1080,1858 #7f0a0159 app:id/recyclerViewTaskLists}, adapter:com.helpinghandsorg.helpinghands.adaptor.MyAdaptor@368f5e0, layout:androidx.recyclerview.widget.LinearLayoutManager@9db2099, context:com.helpinghandsorg.helpinghands.Main2Activity@5c506fd
        at androidx.recyclerview.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:6183)
        at androidx.recyclerview.widget.GapWorker.prefetchPositionWithDeadline(GapWorker.java:288)
        at androidx.recyclerview.widget.GapWorker.flushTaskWithDeadline(GapWorker.java:345)
        at androidx.recyclerview.widget.GapWorker.flushTasksWithDeadline(GapWorker.java:361)
        at androidx.recyclerview.widget.GapWorker.prefetch(GapWorker.java:368)
        at androidx.recyclerview.widget.GapWorker.run(GapWorker.java:399)
        at android.os.Handler.handleCallback(Handler.java:873)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:214)
        at android.app.ActivityThread.main(ActivityThread.java:7099)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:494)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:965)

MyAdaptor我的适配器

public class MyAdaptor extends RecyclerView.Adapter<MyAdaptor.myViewHolder> {

    private Context context;
    private ArrayList<TaskModel> taskLists;
    private int counter = 0;
    private Boolean success = false;
    private String taskid;
    private OnTaskClickListner mTaskListner;
    private int newPosition;

    public MyAdaptor(Context c, ArrayList<TaskModel> t, OnTaskClickListner onTaskClickListner) {
        context = c;
        taskLists = t;
        this.mTaskListner = onTaskClickListner;
    }

    @NonNull
    @Override
    public myViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
        View view = layoutInflater.inflate(R.layout.task_preview, parent, false);
        myViewHolder viewHolder = new myViewHolder(view, mTaskListner);
        return viewHolder;
    }

    @Override
    public void onBindViewHolder(@NonNull myViewHolder holder, final int position) {
        newPosition = holder.getAdapterPosition();
        holder.title.setText(taskLists.get(position).getTaskTitle());
        holder.dueDate.setText(taskLists.get(position).getDueDate());
        holder.description.setText(taskLists.get(position).getTaskDescription());
        holder.deleteButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                taskid = taskLists.get(position).getTaskID();
                new AlertDialog.Builder(context)
                        .setTitle(R.string.confirm_text)
                        .setMessage(R.string.confirm_text_description)
                        .setPositiveButton(R.string.positive_text, new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                FirebaseDatabase.getInstance()
                                        .getReference("tasks")
                                        .child(taskid)
                                        .removeValue(new DatabaseReference.CompletionListener() {
                                            @Override
                                            public void onComplete(@Nullable DatabaseError databaseError, @NonNull DatabaseReference databaseReference) {
                                                taskLists.remove(position);
                                                notifyItemRemoved(position);
                                                Log.d("tasklist", String.valueOf(taskLists.size()));
                                                notifyItemRangeInserted(position, taskLists.size()-1);
                                                Toast.makeText(context, "Delete Successful", Toast.LENGTH_SHORT).show();
                                            }
                                        });
                            }
                        })
                        .setNegativeButton(R.string.negative_text, new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                dialog.cancel();
                            }
                        }).show();
            }
        });

    }

    @Override
    public int getItemCount() {
        return taskLists.size();
    }

    class myViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
        TextView title, dueDate, description;
        ImageButton deleteButton;
        OnTaskClickListner onTaskClickListner;

        public myViewHolder(@NonNull View itemView, OnTaskClickListner onTaskClickListner) {
            super(itemView);
            title = itemView.findViewById(R.id.taskTitle);
            dueDate = itemView.findViewById(R.id.taskDueDate);
            description = itemView.findViewById(R.id.taskDescription);
            deleteButton = itemView.findViewById(R.id.taskDeleteButton);
            this.onTaskClickListner = onTaskClickListner;

            itemView.setOnClickListener(this);

        }

        public ImageButton getDeleteButton() {
            return deleteButton;
        }

        @Override
        public void onClick(View v) {

            onTaskClickListner.onTaskClick(getAdapterPosition());
        }
    }

    public interface OnTaskClickListner {
        void onTaskClick(int position);
    }
}

UPDATE: Change position to holder.getAdapterPosition() when you need position in anonymous class.and make position non final in onBindViewHolder() method; UPDATE: Change position to holder.getAdapterPosition() when you need position in anonymous class.and make position non final in onBindViewHolder() method;

public void onBindViewHolder(@NonNull final myViewHolder holder, int position)

and:和:

holder.deleteButton.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        taskid = taskLists.get(holder.getAdapterPosition()).getTaskID();
        new AlertDialog.Builder(context)
                .setTitle(R.string.confirm_text)
                .setMessage(R.string.confirm_text_description)
                .setPositiveButton(R.string.positive_text, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        FirebaseDatabase.getInstance()
                                .getReference("tasks")
                                .child(taskid)
                                .removeValue(new DatabaseReference.CompletionListener() {
                                    @Override
                                    public void onComplete(@Nullable DatabaseError databaseError, @NonNull DatabaseReference databaseReference) {
                                        taskLists.remove(holder.getAdapterPosition());
                                        notifyItemRemoved(holder.getAdapterPosition());
                                        Log.d("tasklist", String.valueOf(taskLists.size()));

                                        Toast.makeText(context, "Delete Successful", Toast.LENGTH_SHORT).show();
                                    }
                                });
                    }
                })
                .setNegativeButton(R.string.negative_text, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.cancel();
                    }
                }).show();
    }
});

Edit: you must remove notifyItemIRangeInserted() .when you adding items in your list you must call notifyItemIRangeInserted .So just call notifyItemRemoved编辑:您必须删除notifyItemIRangeInserted() 。当您在列表中添加项目时,您必须调用notifyItemIRangeInserted 。所以只需调用notifyItemRemoved

When you are deleting an item you are basically reducing the size of your list, so which also means that the size which you are returning from your getItemCount() should also be reduced.当您删除一个项目时,您基本上是在减小列表的大小,因此这也意味着您从 getItemCount() 返回的大小也应该减小。 Try this: Have a global variable which indicates the size of your list and return that from your getItemCount() when you delete an instance from list, update that variable by decrementing it and then call notifyDataSetChanged()试试这个:有一个全局变量,它指示列表的大小,并在您从列表中删除实例时从 getItemCount() 返回该变量,通过递减该变量来更新该变量,然后调用 notifyDataSetChanged()

The issue, you're using a dynamic list and retrieving data directly from a list that is rather dynamic.问题是,您正在使用动态列表并直接从相当动态的列表中检索数据。 Instead, you should have a global variable inside your adapter and assign the data to it.相反,您应该在适配器内部有一个全局变量并将数据分配给它。 Then, whenever the data changes, you can call "notifyDataSetChanged()".然后,每当数据发生变化时,您都可以调用“notifyDataSetChanged()”。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 RecyclerView:检测到不一致。 无效项目 position - 为什么? - RecyclerView: Inconsistency detected. Invalid item position - why is that? Recyclerview java.lang.IndexOutOfBoundException - Recyclerview java.lang.IndexOutOfBoundException 检测到不一致。 无效的项目位置0(偏移:-1)…删除第一个项目时,RecyclerView崩溃 - Inconsistency detected. Invalid item position 0(offset:-1)… RecyclerView crashes, on deleting first item RecyclerView:检测到不一致。 无效的项目位置。 原因 - 使用计时器删除项目 - RecyclerView: Inconsistency detected. Invalid item position. Cause -Removing item using timer 滚动滚动获取RecyclerView异常:-“ java.lang.IndexOutOfBoundsException:检测到不一致。 无效的商品位置21” - On scroll the RecyclerView getting exception : -“ java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid item position 21” 不一致检测到无效的 View Holder 适配器错误 - Inconsistency Detected Invalid View Holder Adapter Error 添加notifyDataSetChanged()后检测到不一致错误 - Inconsistency detected error after adding notifyDataSetChanged() 在λ形状分析期间检测到内部不一致 - Internal inconsistency detected during lambda shape analysis 在RecyclerView for Intent中未检测到OnClick - OnClick not being detected in RecyclerView for Intent IndexOutOfBoundException(JAVA) - IndexOutOfBoundException(Java)
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM