Update PDF annotation properties in Flutter

This guide shows you how to update PDF annotation properties in Flutter while preserving all annotation metadata.

How it works

To update annotation properties programmatically, follow these steps:

  1. Retrieve annotation properties with getAnnotationProperties().
  2. Update properties using immutable withX() methods.
  3. Save changes with saveAnnotationProperties().
  4. Changes persist immediately to the document.

Basic usage

// Get annotation properties.
final properties = await document.getAnnotationProperties(pageIndex, annotationId);
// Update properties (chain multiple updates).
final updated = properties
?.withColor(Colors.red)
.withOpacity(0.7)
.withLineWidth(3.0);
// Save changes.
if (updated != null) {
await document.saveAnnotationProperties(updated);
}

Common operations

The following examples demonstrate common ways to modify annotation properties such as color, opacity, and flags.

Update color

final updated = properties?.withColor(Colors.blue);
await document.saveAnnotationProperties(updated);

Update opacity

final updated = properties?.withOpacity(0.5); // 0.0 to 1.0
await document.saveAnnotationProperties(updated);

Update line width

final updated = properties?.withLineWidth(2.5);
await document.saveAnnotationProperties(updated);

Toggle flags

final flags = properties?.flagsSet ?? {};
final newFlags = Set<AnnotationFlag>.from(flags);
newFlags.contains(AnnotationFlag.readOnly)
? newFlags.remove(AnnotationFlag.readOnly)
: newFlags.add(AnnotationFlag.readOnly);
final updated = properties?.withFlags(newFlags);
await document.saveAnnotationProperties(updated);

Update custom data

final data = {
...(properties?.customData ?? {}),
'key': 'value',
};
final updated = properties?.withCustomData(data);
await document.saveAnnotationProperties(updated);

Available methods

MethodParameterDescription
withColor()ColorUpdate color
withOpacity()doubleUpdate opacity (0.0–1.0)
withLineWidth()doubleUpdate line width
withFlags()Set<AnnotationFlag>Update flags
withCustomData()Map<String, String>Update custom data
withBoundingBox()RectUpdate position/size
withContents()StringUpdate text content
withSubject()StringUpdate subject

Common flags

AnnotationFlag.hidden // Hidden from view.
AnnotationFlag.print // Printable.
AnnotationFlag.readOnly // No user interaction.
AnnotationFlag.locked // Cannot delete/modify.
AnnotationFlag.lockedContents // Contents locked.

With selection events

controller.addEventListener(NutrientEvent.annotationsSelected, (event) async {
final annotation = event?['annotation'];
final annotationId = annotation?.id ?? annotation?.name;
if (annotationId != null) {
final properties = await document.getAnnotationProperties(
annotation.pageIndex,
annotationId,
);
final updated = properties?.withColor(Colors.red);
if (updated != null) {
await document.saveAnnotationProperties(updated);
}
}
});

Migration from deprecated API

This section shows how to migrate from the deprecated annotation update API to the new properties-based approach that safely retains metadata.

Old:

final annotation = await document.getAnnotation(pageIndex, annotationId);
await document.updateAnnotation(annotation.copyWith(color: Colors.red));
// Loses metadata.

New:

final properties = await document.getAnnotationProperties(pageIndex, annotationId);
final updated = properties?.withColor(Colors.red);
if (updated != null) {
await document.saveAnnotationProperties(updated);
}
// Preserves all data.