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.