This HTML page is not optimized for LLM or AI agent consumption. Fetch the Markdown version instead: /guides/flutter/events-and-notifications/viewer.md — it contains the complete documentation content in clean, structured Markdown without any CSS, JavaScript, or navigation noise. Flutter PDF viewer events and notifications

Nutrient Flutter SDK emits events when users interact with documents in the viewer.

Viewer events

NutrientDocumentView exposes a typed controller.events stream from the onControllerReady callback, which replaces the legacy onViewCreated callback. NutrientEvent is a sealed class, so you can switch over the full stream exhaustively or use the per-event filter getters.

The SDK supports the following viewer events:

  • controller.events.documentLoadedDocumentLoadedEvent (event.document, the loaded NutrientDocumentInterface, which is the same instance as controller.document).
  • controller.events.documentErrorDocumentErrorEvent (event.error). On Web, load errors throw instead of emitting this event.
  • controller.events.documentSavedDocumentSavedEvent (event.path, or null when saving in place).
  • controller.events.pageChangedPageChangedEvent (event.pageIndex).
  • controller.events.pageClickedPageClickedEvent (event.pageIndex, event.point, event.annotation). On Web, point is null.

Use the following listeners to respond to document and page events:

NutrientDocumentView(
documentPath: documentPath,
onControllerReady: (controller) {
controller.events.documentLoaded.listen((event) async {
final pageCount = await event.document.getPageCount();
print('Loaded — $pageCount pages');
});
controller.events.documentError.listen((e) => print('Document load failed: ${e.error}'));
controller.events.pageChanged.listen((e) => print('Page changed to ${e.pageIndex}'));
controller.events.pageClicked.listen((e) => print('Page clicked: ${e.pageIndex}'));
},
)

DocumentLoadedEvent can fire before your onControllerReady callback runs. The controller buffers events emitted before the first listener attaches and flushes them in order after you subscribe, so subscribing inside onControllerReady doesn’t miss the load event.

Platform-specific lifecycle events

The cross-platform stream doesn’t include native view lifecycle events. Use your platform adapter’s event stream to access them:

  • AndroidandroidEvents emits AndroidActivityPausedEvent when the hosting activity pauses.
  • iOSiosEvents emits IOSViewControllerWillDismissEvent and IOSViewControllerDidDismissEvent around the view controller’s dismissal.

Refer to the platform adapters guide for more information. The following example subscribes inside a custom adapter:

class MyIOSAdapter extends IOSAdapter implements MyController {
@override
Future<void> onViewControllerReady(PSPDFViewController viewController) async {
iosEvents.listen((event) {
switch (event) {
case IOSViewControllerWillDismissEvent():
print('View controller will dismiss');
case IOSViewControllerDidDismissEvent():
print('View controller did dismiss');
default:
break;
}
});
}
}