You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

RecyclerView删除、撤销删除及永久删除功能实现问题求助

RecyclerView删除、撤销删除及永久删除功能实现问题求助

各位好,我现在在开发一个笔记应用的RecyclerView相关功能时遇到了几个棘手的问题,麻烦大家帮忙看看:

遇到的具体问题

  • 空指针异常:点击删除按钮时会抛出java.lang.NullPointerException: Attempt to invoke interface method 'NoteAdapter$onItemListener.onItemClick(java.lang.String)' on a null object reference,报错指向我的ViewHolder类里的timeNameHolder.onClick方法。
  • 选中状态异常:删除笔记后点击撤销(UNDO)恢复该笔记时,恢复的笔记确实会正确高亮,但原本顶替被删笔记位置的那个笔记,现在回到原位置后也保持了高亮状态,没有恢复默认样式。
  • 偶尔出现数组越界:有时候操作过程中会触发索引越界的错误,暂时没找到稳定复现的规律。

核心代码片段

noteAdapter.setOnItemClickListener(new NoteAdapter.OnItemClickListener() {
    @Override
    public void onItemSelect(int position, timeNameViewHolder holder) {
        try {
            isNotifEnabled = false;
            DataHolder.creatingNote = false;
            current = java.util.Calendar.getInstance();
            selectedPosition = position;
            System.out.println("onItemSelect position: " + position);
            selectedNote = noteAdapter.getCurrentNotes().get(position);
            selectedNoteId = selectedNote.getNoteId();
            if (DataHolder.hideEditButton != true) {
                Save.setVisibility(View.VISIBLE);
                Save.setText("Create");
            }
            noteAdapter.setSelectedPosition(position);
            linearLayoutMA4.setVisibility(View.VISIBLE);
            linearLayoutMA3.setVisibility(View.GONE);
            toolbar.setTitle("Your Notes");
            String titleEntered = selectedNote.getTitle();
            String descriptionEntered = selectedNote.getDescription();
            created = selectedNote.getCreatedAt();
            long updated = selectedNote.getUpdatedAt();
            enteredTitle.setText(titleEntered);
            enteredDescription.setText(descriptionEntered);
            getSetUpdated(created, updated, selectedNote);
            long currenMilliTime = current.getTimeInMillis();
            if (DataHolder.notificationTime(selectedNote) > currenMilliTime) {
                notifiActiveOff1.setImageResource(R.drawable.notifications_active);
                notificationText1.setText("Notification On");
                notifiActiveOff2.setImageResource(R.drawable.notifications_active);
                notificationText2.setText("Notification On");
                isNotificationOn = true;
            } else {
                notifiActiveOff1.setImageResource(R.drawable.notifications_off);
                notificationText1.setText("Notification Off");
                notifiActiveOff2.setImageResource(R.drawable.notifications_off);
                notificationText2.setText("Notification Off");
            }
        } catch (Exception e) {
        }
    }

    @Override
    public void onEditClick(int noteId, String title, String description){
        try {
            isNotifEnabled = true;
            DataHolder.creatingNote = false;
            enterTittle.setText(title);
            enterDescription.setText(description);
            selectedNoteId = noteId;
            Save.setText("Save");
            toolbar.setTitle("Editing Notes");
            isEditing = true;
            linearLayoutMA4.setVisibility(View.GONE);
            linearLayoutMA3.setVisibility(View.VISIBLE);
            enteredTitle.setText("");
            enteredDescription.setText("");
        } catch (Exception e) {
        }
    }

    @Override
    public void onDeleteClick(int position, int noteId, timeNameViewHolder holder) {
        DataHolder.creatingNote = false;
        //CANCEL NOTIFICATION DISPLAYED IN NOTIFICATION BAR IF CANCELLED HERE
        if (isDeleting) {
            return;
        }
        isDeleting = true;
        if (selectedNoteId == -1) {
            //isDeleting = false;
            //return;
        }
        final int deletedPosition = selectedPosition;
        if (deletedPosition < 0 || deletedPosition >= noteAdapter.getItemCount()) {
            //isDeleting = false;
            //return;
        }
        final Note noteToDelete = noteAdapter.getNoteAt(deletedPosition);
        if (currentSnackbar != null && currentSnackbar.isShown()) {
            currentSnackbar.dismiss();
        }
        noteAdapter.getCurrentNotes().remove(deletedPosition);
        noteAdapter.notifyItemRemoved(deletedPosition);
        deleteQueue.offer(new PendingDelete(noteToDelete, deletedPosition));
        clearNoteUI();
        new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
            @Override
            public void run() {
                if (noteAdapter.getItemCount() > 0) {
                    int newPosition;
                    if (deletedPosition == 0) {
                        newPosition = 0;
                    } else {
                        newPosition = deletedPosition - 1;
                    }
                    noteAdapter.setSelectedPosition(newPosition);
                    updateUIWithNote(noteAdapter.getNoteAt(newPosition));
                } else {
                    noteAdapter.resetSelection();
                }
            }
        }, 200);

        // Create new Snackbar
        currentSnackbar = Snackbar.make(recyclerView, "Note deleted", Snackbar.LENGTH_LONG);
        currentSnackbar.setAction("UNDO", new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                PendingDelete pendingDelete = deleteQueue.poll();
                if (pendingDelete != null) {
                    Note restoredNote = pendingDelete.getNote();
                    int restorePosition = pendingDelete.getPosition();
                    noteAdapter.getCurrentNotes().add(restorePosition, restoredNote);
                    noteAdapter.notifyItemInserted(restorePosition);
                    noteAdapter.setSelectedPosition(restorePosition);
                }
            }
        });
        currentSnackbar.show();
    }
});

我的疑惑

我怀疑选中状态的管理可能有漏洞,比如撤销恢复后没有正确重置其他项的选中状态;空指针可能和ViewHolder的点击监听绑定不完整有关?但反复检查后还是没找到具体问题点。有没有大佬能帮我分析下问题根源,或者给一些调试的方向?

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.08 11:18:00