java - IndexOutOfBoundException 在 recyclerview 上检测到不一致

标签 java android android-recyclerview

您好,我正在尝试从回收器 View 中删除一个项目,但在成功删除后,当我滚动到底部时,应用程序崩溃并显示此错误。我尝试打电话

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

但它仍然没有修复,我不确定我是否正确调用了这些函数。

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)

我的适配器

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

最佳答案

当您删除一个项目时,您基本上会减小列表的大小,因此这也意味着您从 getItemCount() 返回的大小也应该减小。 试试这个:有一个全局变量来指示列表的大小,并在从列表中删除实例时从 getItemCount() 返回该变量,通过递减该变量来更新该变量,然后调用 notificationDataSetChanged()

关于java - IndexOutOfBoundException 在 recyclerview 上检测到不一致,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61700398/

相关文章:

java - 如何对直接在webapps下的资源请求应用过滤器

android - Android 设备支持的 LED

javascript - 在 Slack 消息中格式化电话号码?

java - 仅在输入停止一段时间后进行处理

java - 当需要 Completable<Void> 时返回 Completable<Object>

java - 如何在 Selenium 中打印页面中的所有链接并选择任意 3 个随机 URL

java - 如何在 android imageview 中显示 SVG 图像

android - IntelliJ 预览版 RecyclerView API 级别 25

android - RecyclerView "cannot resolve symbol"错误 - Android Studio

java - Recyclerview旋转显示时丢失数据,按下按钮时加载数据Android