---
title: "Nutrient Android SDK 11.3 release notes"
canonical_url: "https://www.nutrient.io/guides/android/releases/11-3/"
md_url: "https://www.nutrient.io/guides/android/releases/11-3.md"
last_updated: "2026-05-23T00:08:17.995Z"
description: "Release notes for Nutrient Android SDK 11.3, including annotation mode unification and annotation editing toolbar removal."
---

26 Mar 2026

Nutrient Android SDK 11.3 unifies annotation creation and editing into a single “annotating” mode. The previously separate annotation creation and annotation editing modes — each with their own controllers, listeners, and inspector controllers — are now handled by a unified set of APIs. As part of this change, the `AnnotationEditingToolbar` has been removed and replaced by a popup toolbar that appears directly next to the selected annotation.

This is a breaking change. Refer to the [migration guide](#migration-guide) below for details on updating your code.

This release contains several fixes and enhancements. For the full list of changes, refer to our [changelog](https://www.nutrient.io/guides/android/changelog.md#11.3.0).

## UI improvements

- Icons have been added to the annotation popup toolbar with improved UI styling and animations.

- Icons have been added to the text selection and long-press popup toolbars.

- Touch animations have been added to text selection handles with scale-up on press, finger tracking during drag, and smooth return animation on release.

- The magnifier view has been improved with an animation and a higher position for better visibility.

- Annotation toolbar buttons now show a tooltip on long-press instead of a toast.

- `TextSelectionToolbar` and the `isTextSelectionPopupToolbarEnabled` configuration option have been deprecated. The popup toolbar is now the only supported text selection toolbar; the legacy toolbar will be removed in a future version.

## Bug fixes

This release addresses issues in both the user interface and underlying model layer.

### UI

- Fixed `DocumentView` position and popup toolbar placement breaking after exiting form or content editing mode.

- Fixed a crash when tapping form elements due to uninitialized property access in `ExtractedFormElementView`.

- Fixed a race condition where the low-resolution page bitmap cache could briefly show an annotation with outdated properties.

- Fixed an issue where dragging after long-pressing to select text would scroll the page, causing the popup toolbar to flicker.

- Fixed an issue where erasing a pending ink annotation could remain partially visible until rendering catches up.

- Fixed annotation selection not working after dismissing text selection in annotation creation mode.

- Fixed cursor positioning when tapping in empty space to the right of a line’s text in content editing, which incorrectly placed the cursor at the beginning of the next line instead of the end of the tapped line.

- Fixed form editing mode activating when tapping an annotation that overlaps a form field.

- Fixed freezes when erasing ink annotations at high zoom levels by clamping eraser radius handling and sampling work.

- Fixed the measurement scale FAB not showing when selecting a measurement annotation.

- Fixed pinch-to-zoom accidentally triggering text selection in annotation mode.

- Fixed space character input occasionally being swallowed during content editing on Samsung devices.

- Fixed text selection handles not allowing shortening of the selection by dragging inward.

- Fixed the document jumping back to the first page after a content editing save operation when the `restoreLastViewedPage` option is enabled.

- Fixed an issue where tapping a free text annotation to start editing would trigger drag detection and hide the keyboard and UI.

- Fixed ANRs caused by smart zoom text lookup blocking the main thread during double-tap.

- Fixed drawable providers not rendering on scrollable thumbnail bar mode.

- Fixed search highlights and annotation drawables disappearing after page recycling.

- Fixed IME extract mode (fullscreen editing) not activating for content editing in landscape mode.

- Fixed the thumbnail bar not being displayed after a document editing action.

- Fixed the thumbnail bar showing the wrong page after saving a content editing session.

- Fixed a potential rare crash in the thumbnail bar with recycled bitmaps when Compose abandons a composition during rapid scrolling.

- Fixed an issue with page rendering moving incorrectly at very high zoom levels by limiting default max zoom.

### Model

- Improved memory pressure log messages to be less alarming and more informative.

- Improved paragraph detection for content editing on PDF/UA documents.

- Readded the `FreeTextAnnotation.resizeToFitText()` Kotlin extension function that was accidentally removed in 10.8.0. See [`FreeTextAnnotationUtils` changes](#freetextannotationutils-changes) for details.

- Fixed a crash caused by `ClosedByInterruptException` during document opening when the IO thread is interrupted.

- Fixed a regression where adjusting the opacity slider on certain annotations didn’t correctly update the fill opacity (for example, on highlight annotations).

- Fixed an issue where content editing didn’t update the modification date of the PDF.

- Fixed an issue where repeated redactions on certain image-based PDFs could cause the page colors to toggle or appear inverted.

- Fixed content editing mismatch warnings to show the original PDF font name instead of the substituted fallback font.

## Popup toolbar customization

The new annotation popup toolbar (which replaces the removed `AnnotationEditingToolbar`) can be customized via the [`OnPreparePopupToolbarListener`](https://www.nutrient.io/api/android/nutrient/com.pspdfkit.listeners/-on-prepare-popup-toolbar-listener/index.html). This listener now provides callbacks for all popup toolbar types:

- `onPrepareAnnotationPopupToolbar(AnnotationPopupToolbar)` — **New**, called when the annotation popup toolbar is about to be displayed. `AnnotationPopupToolbar` is a new public class extending `PopupToolbar` that exposes an `annotations` property containing the currently selected annotations.

- `onPrepareTextSelectionPopupToolbar(TextSelectionPopupToolbar)` — Called when the text selection popup toolbar is about to be displayed.

- `onPrepareLongPressPopupToolbar(PopupToolbar, int pageIndex, PointF pdfPoint)` — **New**, called when the long-press popup toolbar is about to be displayed. This toolbar appears when the user long-presses on an empty area of a document (outside of text selection or annotation selection). The `pageIndex` and `pdfPoint` parameters indicate where the long-press occurred in PDF coordinates.

- `onPrepareContentEditingPopupToolbar(PopupToolbar, int pageIndex, PointF pdfPoint)` — **New**, called when a content editing popup toolbar is about to be displayed. This toolbar appears when the user long-presses in content editing mode, either on a text block or on an empty area of the page. The `pageIndex` and `pdfPoint` parameters indicate where the long-press occurred in PDF coordinates.

---

## Migration guide

This section covers breaking changes and how to update your code.

### Annotation editing toolbar removal

The `AnnotationEditingToolbar` — the bar shown at the top or bottom of the screen when an annotation was selected — has been removed. Annotation editing actions (delete, edit, inspector, note, share, copy, play/record for sound) are now provided by a popup toolbar that appears next to the selected annotation on the page.

#### Removed classes

The following classes have been fully removed with no direct replacement. The popup toolbar is managed automatically by the SDK:

- `com.pspdfkit.ui.toolbar.AnnotationEditingToolbar`

- `com.pspdfkit.ui.toolbar.grouping.presets.AnnotationEditingToolbarGroupingRule`

- `com.pspdfkit.ui.toolbar.grouping.presets.AnnotationEditingToolbarItemPresets`

#### What to remove from your code

- **`AnnotationEditingToolbar` instantiation** — Remove entirely. The popup toolbar is managed automatically.

- **`bindController()`/`unbindController()` calls** on `AnnotationEditingToolbar` — Remove these calls.

- **`displayContextualToolbar()`/`removeContextualToolbar()` calls** for annotation editing — Remove these calls.

- **`instanceof AnnotationEditingToolbar` checks** in `onPrepareContextualToolbar` — Remove these branches. The `OnContextualToolbarLifecycleListener` callbacks no longer fire for annotation editing.

- **Styling via `pspdf__annotationEditingToolbarIconsStyle`, `pspdf__AnnotationEditingToolbarIcons`, or `PSPDFKit.AnnotationEditingToolbarIcons`** — No longer applies to annotation editing. If you were using these to customize note editor toolbar icons, see the [styling migration](#styling-migration) section below.

- **Custom `AnnotationEditingToolbarGroupingRule` subclasses** — No longer apply.

#### Popup toolbar actions

The popup toolbar provides actions based on the selected annotation type:

| Action                             | Conditions                                                                                  |
| ---------------------------------- | ------------------------------------------------------------------------------------------- |
| **Copy**                           | When copy is enabled for the selected annotations                                           |
| **Delete**                         | When delete is enabled (not shown for Instant comment thread roots)                         |
| **Inspector** (color/style picker) | Not shown for note or sound annotations or Instant comment thread roots                     |
| **Note/Comment**                   | For annotations that support notes (not for note annotations themselves)                    |
| **Edit**                           | For note annotations (opens the note editor)                                                |
| **Play / Record**                  | For sound annotations                                                                       |
| **Share**                          | For annotation types with sharing enabled (free text, note, file, stamp with bitmap, sound) |
| **Ungroup / Group**                | When selected annotations can be ungrouped or grouped                                       |

#### Styling migration

The removed `AnnotationEditingToolbar` style names don’t style the new annotation popup toolbar.

- The annotation popup toolbar is styled via `pspdf__popupToolbarStyle`/`PSPDFKit.PopupToolbar`.

- The popup toolbar uses text actions, not per-action themed icons, so there’s no direct replacement for old icon overrides like edit, share, copy, play, or record.

- The note editor still has its own top app bar with undo/redo/delete actions. If you previously used the removed editing toolbar icon style names to customize those icons, rename them to the note editor toolbar names:

| Old name                                    | New name                             |
| ------------------------------------------- | ------------------------------------ |
| `pspdf__annotationEditingToolbarIconsStyle` | `pspdf__noteEditorToolbarIconsStyle` |
| `pspdf__AnnotationEditingToolbarIcons`      | `pspdf__NoteEditorToolbarIcons`      |
| `PSPDFKit.AnnotationEditingToolbarIcons`    | `PSPDFKit.NoteEditorToolbarIcons`    |

### Controller and listener unification

Annotation creation and annotation editing were previously two separate modes with separate controllers and listeners. They have been unified into a single “annotating” mode.

#### Core concept change

| Before                                                         | After                                   |
| -------------------------------------------------------------- | --------------------------------------- |
| Two separate modes: annotation creation and annotation editing | One unified mode: annotating            |
| `AnnotationCreationController` for creation                    | `AnnotatingController` for both         |
| `AnnotationEditingController` for editing                      | `AnnotatingController` for both         |
| Separate listeners for each mode                               | Single `OnAnnotatingModeChangeListener` |
| Separate inspector controllers                                 | Single `AnnotatingInspectorController`  |

#### Deleted interfaces

| Deleted interface                                | Replacement                              |
| ------------------------------------------------ | ---------------------------------------- |
| `AnnotationCreationController`                   | `AnnotatingController`                   |
| `AnnotationEditingController`                    | `AnnotatingController`                   |
| `OnAnnotationCreationModeChangeListener`         | `OnAnnotatingModeChangeListener`         |
| `OnAnnotationEditingModeChangeListener`          | `OnAnnotatingModeChangeListener`         |
| `OnAnnotationCreationModeSettingsChangeListener` | `OnAnnotatingModeSettingsChangeListener` |
| `AnnotationCreationInspectorController`          | `AnnotatingInspectorController`          |
| `AnnotationEditingInspectorController`           | `AnnotatingInspectorController`          |

Note that `AnnotationCreationController` was previously kept as a deprecated empty alias of `AnnotatingController`. That alias has now been removed, so code must migrate directly to `AnnotatingController`.

#### Deprecated (still available)

`PdfFragment#enterAnnotationEditingMode()` (both overloads) is deprecated. Use `PdfFragment.setSelectedAnnotations()` instead. There’s no need to enter annotating mode to edit annotations — the popup toolbar handles editing actions automatically.

`PdfFragment#enterAnnotationCreationMode()` (all overloads) is deprecated. Use `enterAnnotatingMode()`, `enterAnnotatingMode(AnnotationTool)`, or `enterAnnotatingMode(AnnotationTool, AnnotationToolVariant)` instead.

#### Changed methods on PdfFragment

| Removed method                                           | Replacement                                      |
| -------------------------------------------------------- | ------------------------------------------------ |
| `addOnAnnotationCreationModeChangeListener()`            | `addOnAnnotatingModeChangeListener()`            |
| `removeOnAnnotationCreationModeChangeListener()`         | `removeOnAnnotatingModeChangeListener()`         |
| `addOnAnnotationCreationModeSettingsChangeListener()`    | `addOnAnnotatingModeSettingsChangeListener()`    |
| `removeOnAnnotationCreationModeSettingsChangeListener()` | `removeOnAnnotatingModeSettingsChangeListener()` |
| `addOnAnnotationEditingModeChangeListener()`             | `addOnAnnotatingModeChangeListener()`            |
| `removeOnAnnotationEditingModeChangeListener()`          | `removeOnAnnotatingModeChangeListener()`         |

#### Changed methods on PdfUi/PdfActivityComponentsApi

| Removed method                               | Replacement                        |
| -------------------------------------------- | ---------------------------------- |
| `setAnnotationEditingInspectorController()`  | `setEditingInspectorController()`  |
| `setAnnotationCreationInspectorController()` | `setCreationInspectorController()` |

#### Removed deprecated inner interfaces from AnnotationManager

These deprecated compatibility shim interfaces have been removed:

- `AnnotationManager.OnAnnotationCreationModeChangeListener`

- `AnnotationManager.OnAnnotationCreationModeSettingsChangeListener`

- `AnnotationManager.OnAnnotationEditingModeChangeListener`

`AnnotationManager.OnAnnotationSelectedListener` still remains.

#### AnnotationCreationToolbar renamed to AnnotationToolbar

`AnnotationCreationToolbar` has been renamed to `AnnotationToolbar`. The toolbar’s generic type and listener interfaces have also changed,

**Before:**

```kotlin

class AnnotationCreationToolbar :
    ContextualToolbar<AnnotationCreationController>,
    OnAnnotationCreationModeSettingsChangeListener,
    OnAnnotationCreationModeChangeListener {... }

```

**After:**

```kotlin

class AnnotationToolbar :
    ContextualToolbar<AnnotatingController>,
    OnAnnotatingModeSettingsChangeListener,
    OnAnnotatingModeChangeListener,
    OnAnnotationSelectedListener {... }

```

The nested type `AnnotationCreationToolbar.ItemToAnnotationToolMapper` is now `AnnotationToolbar.ItemToAnnotationToolMapper`.

The `controller` property type changed from `AnnotationCreationController?` to `AnnotatingController?`, and the `bindController()` parameter type changed from `AnnotationCreationController` to `AnnotatingController`.

Note that grouping rules (`AnnotationCreationToolbarGroupingRule`), item presets (`AnnotationCreationToolbarItemPresets`), item groups (`AnnotationCreationToolbarItemGroups`), and style attributes (`pspdf__annotationCreationToolbarIconsStyle`, `pspdf__AnnotationCreationToolbarIcons`, `PSPDFKit.AnnotationCreationToolbarIcons`) are **unchanged**.

#### Resource ID renames

All annotation toolbar XML resource IDs have been renamed to match the new class name:

| Old ID prefix                          | New ID prefix                 |
| -------------------------------------- | ----------------------------- |
| `pspdf__annotation_creation_toolbar_*` | `pspdf__annotation_toolbar_*` |

For example, `R.id.pspdf__annotation_creation_toolbar` is now `R.id.pspdf__annotation_toolbar`, `R.id.pspdf__annotation_creation_toolbar_item_highlight` is now `R.id.pspdf__annotation_toolbar_item_highlight`, and so on for all toolbar item and group IDs.

The old annotation editing toolbar IDs have been renamed to annotation popup toolbar IDs:

| Old ID prefix                         | New ID prefix                       |
| ------------------------------------- | ----------------------------------- |
| `pspdf__annotation_editing_toolbar_*` | `pspdf__annotation_popup_toolbar_*` |

For example, `R.id.pspdf__annotation_editing_toolbar_item_delete` is now `R.id.pspdf__annotation_popup_toolbar_item_delete`.

#### OnPreparePopupToolbarListener is no longer a SAM interface

`OnPreparePopupToolbarListener` previously had a single abstract method (`onPrepareTextSelectionPopupToolbar`), making it usable as a lambda in Kotlin and Java. It now has four `default` methods (see [popup toolbar customization](#popup-toolbar-customization) above for the full list).

Because the interface is no longer a functional interface, **lambda syntax no longer compiles**. Update to use an explicit `object` expression (Kotlin) or anonymous class (Java).

**Before (Kotlin):**

```kotlin

pdfFragment.setOnPreparePopupToolbarListener { toolbar ->
    toolbar.setOnPopupToolbarItemClickedListener { item ->
        // Handle item click.
        false
    }
}

```

**After (Kotlin):**

```kotlin

pdfFragment.setOnPreparePopupToolbarListener(object : OnPreparePopupToolbarListener {
    override fun onPrepareTextSelectionPopupToolbar(toolbar: TextSelectionPopupToolbar) {
        toolbar.setOnPopupToolbarItemClickedListener { item ->
            // Handle item click.
            false
        }
    }
})

```

#### Behavioral change: Annotation deselection

When an annotation is deselected (without reselection) while in annotation mode, the SDK no longer exits the currently active mode. Previously, deselecting an annotation would call `exitCurrentlyActiveMode()`. Now, the annotating mode persists even when annotations are deselected, which allows continued annotation creation and editing.

### Migration examples

The following examples show how to update common code patterns to use the new unified APIs.

#### Migrating annotation creation listener

**Before:**

```java

fragment.addOnAnnotationCreationModeChangeListener(new OnAnnotationCreationModeChangeListener() {
    @Override public void onEnterAnnotationCreationMode(AnnotationCreationController controller) {
        // Handle enter.
    }
    @Override public void onChangeAnnotationCreationMode(AnnotationCreationController controller) {
        // Handle change.
    }
    @Override public void onExitAnnotationCreationMode(AnnotationCreationController controller) {
        // Handle exit.
    }
});

```

**After:**

```java

fragment.addOnAnnotatingModeChangeListener(new OnAnnotatingModeChangeListener() {
    @Override public void onEnterAnnotatingMode(AnnotatingController controller) {
        // Handle enter (covers both creation and editing).
    }
    @Override public void onChangeAnnotatingMode(AnnotatingController controller) {
        // Handle change.
    }
    @Override public void onExitAnnotatingMode(AnnotatingController controller) {
        // Handle exit.
    }
});

```

#### Migrating annotation editing listener

**Before:**

```java

fragment.addOnAnnotationEditingModeChangeListener(new OnAnnotationEditingModeChangeListener() {
    @Override public void onEnterAnnotationEditingMode(AnnotationEditingController controller) {
        annotationEditingToolbar.bindController(controller);
        toolbarCoordinatorLayout.displayContextualToolbar(annotationEditingToolbar, true);
    }
    @Override public void onChangeAnnotationEditingMode(AnnotationEditingController controller) { }
    @Override public void onExitAnnotationEditingMode(AnnotationEditingController controller) {
        toolbarCoordinatorLayout.removeContextualToolbar(true);
        annotationEditingToolbar.unbindController();
    }
});

```

**After:** Editing is handled automatically by the popup toolbar. The toolbar management code is no longer needed. If you need to react to mode changes, use `OnAnnotatingModeChangeListener` (see above).

#### Migrating inspector controller setup

**Before:**

```java

activity.setAnnotationCreationInspectorController(myCreationInspectorController);
activity.setAnnotationEditingInspectorController(myEditingInspectorController);

```

**After:**

```java

activity.setCreationInspectorController(myAnnotatingInspectorController);
activity.setEditingInspectorController(myAnnotatingInspectorController);

```

#### Migrating custom inspector controllers

**Before:**

```java

class MyInspector implements AnnotationCreationInspectorController {
    void bindAnnotationCreationController(AnnotationCreationController controller) {... }
    void unbindAnnotationCreationController() {... }
}

```

**After:**

```java

class MyInspector implements AnnotatingInspectorController {
    void bindController(AnnotatingController controller) {... }
    void unbindController() {... }
}

```

#### Migrating AnnotationToolbar binding

**Before:**

```java

AnnotationCreationToolbar annotationToolbar =...;
AnnotationCreationController controller =...;
annotationToolbar.bindController(controller);

```

**After:**

```java

AnnotationToolbar annotationToolbar =...;
AnnotatingController controller =...;
annotationToolbar.bindController(controller);

```

### FreeTextAnnotationUtils changes

`FreeTextAnnotationUtils` has been converted from a Java utility class to Kotlin top-level extension functions. The `ScaleMode` enum and the `placeCallOutPoints` method have moved, and a new `resizeToFitText` extension function has been added.

#### ScaleMode moved to top-level enum

`ScaleMode` is no longer a nested enum inside `FreeTextAnnotationUtils`. It’s now a top-level enum in the `com.pspdfkit.utils` package.

| Before                                                 | After                          |
| ------------------------------------------------------ | ------------------------------ |
| `com.pspdfkit.utils.FreeTextAnnotationUtils.ScaleMode` | `com.pspdfkit.utils.ScaleMode` |

**Before:**

```kotlin

import com.pspdfkit.utils.FreeTextAnnotationUtils.ScaleMode

val mode = ScaleMode.SCALE

```

**After:**

```kotlin

import com.pspdfkit.utils.ScaleMode

val mode = ScaleMode.SCALE

```

#### placeCallOutPoints is now an extension function

`FreeTextAnnotationUtils.placeCallOutPoints(annotation)` is now an extension function on `FreeTextAnnotation`.

**Before:**

```kotlin

import com.pspdfkit.utils.FreeTextAnnotationUtils

FreeTextAnnotationUtils.placeCallOutPoints(freeTextAnnotation)

```

**After:**

```kotlin

import com.pspdfkit.utils.placeCallOutPoints

freeTextAnnotation.placeCallOutPoints()

```

#### New resizeToFitText extension function

`FreeTextAnnotation.resizeToFitText()` was mistakenly removed in v10.8 and has been readded in this release as a Kotlin extension function on `FreeTextAnnotation`. It resizes the annotation bounding box so the text fits inside its bounds, using the specified `ScaleMode` for width and height independently:

```kotlin

import com.pspdfkit.utils.ScaleMode
import com.pspdfkit.utils.resizeToFitText

// Resize to exactly fit the text content.
freeTextAnnotation.resizeToFitText(document, ScaleMode.SCALE, ScaleMode.SCALE)

// Only expand, never shrink.
freeTextAnnotation.resizeToFitText(document, ScaleMode.EXPAND, ScaleMode.EXPAND)

// Keep width fixed, scale height to fit.
freeTextAnnotation.resizeToFitText(document, ScaleMode.FIXED, ScaleMode.SCALE)

```
---

## Related pages

- [10 10](/guides/android/releases/10-10.md)
- [10 6](/guides/android/releases/10-6.md)
- [10 10 1](/guides/android/releases/10-10-1.md)
- [11 0](/guides/android/releases/11-0.md)
- [10 7](/guides/android/releases/10-7.md)
- [10 9](/guides/android/releases/10-9.md)
- [11 2](/guides/android/releases/11-2.md)
- [10 8](/guides/android/releases/10-8.md)
- [11 1](/guides/android/releases/11-1.md)
- [11 3 1](/guides/android/releases/11-3-1.md)
- [11 4](/guides/android/releases/11-4.md)
- [11 5](/guides/android/releases/11-5.md)

