Undo and redo annotations on Android
Nutrient Android SDK supports undo and redo for creating and editing annotations. Users can undo and redo changes using the undo and redo items of the annotation creation toolbar. Those items carry the action IDs pspdf.undo and pspdf.redo. A host rendering its own toolbar items with the same action IDs gets their enabled state and handling from the SDK. See using contextual toolbars within PdfFragment.

To support undo and redo, we’ve created an interface named UndoManager. The implementation of this interface is provided through the PdfFragment#getUndoManager() method. The UndoManager provides methods for controlling the undo/redo business logic, including:
undo()— Undo the last performed editredo()— Redo the last undone editcanUndo()— Whether or not the undo action can be executedcanRedo()— Whether or not the redo action can be executed
Enabling/disabling undo and redo
Undo and redo operations are enabled by default. However, you can use undoEnabled(boolean) and redoEnabled(boolean) when building a PdfConfiguration to enable or disable undo and redo in your app. Logically, redo can’t be enabled if undo is disabled.
Listening for undo and redo changes
To listen for undo and redo changes, you can attach OnUndoHistoryChangeListener to the UndoManager through addOnUndoHistoryChangeListener(). The callback notifies you once the undo history changes, so you can update the UI or components that depend on the undo/redo state.
Intercepting edits
To intercept editing operations, implement the OnAddNewEditListener interface and add it to the UndoManager. The listener is notified when edits are about to be added, so you can read their details or block them from entering the undo stack.
Here’s an example that blocks annotation creation from being added to the undo stack:
class MyActivity : PdfActivity(), OnAddNewEditListener {
override fun onDocumentLoaded(document: PdfDocument) { super.onDocumentLoaded(document) // Hook listener to the SDK. pdfFragment?.undoManager?.setOnAddNewEditListener(this) }
override fun onAddNewEdit(edit: Edit): Boolean { // This override blocks an edit that is triggered from adding an annotation. // It allows every other edit operation to be added to the undo stack. return !(edit is AnnotationAddRemoveEdit && edit.type == AnnotationAddRemoveEdit.Type.ADD_ANNOTATION) }}Current limitations
- Currently, undo/redo history is tracked for annotations and content editing operations.