
Syncfusion Flutter Pdf Viewer
- 1 installs
- 1 repo stars
- Updated July 6, 2026
- syncfusion/pdf-viewer-sdk-skills
Scaffolds a Flutter project and generates Dart code to embed and configure the Syncfusion SfPdfViewer widget for loading PDF documents.
About
Scaffolds a Flutter project with syncfusion_flutter_pdfviewer and generates Dart code for the SfPdfViewer widget. A developer uses it when embedding and configuring a PDF viewer in a Flutter mobile, desktop, or web app.
- Uses the syncfusion_flutter_pdfviewer pub.dev package
- Handles project creation, dependency setup, and web PdfJs configuration
Syncfusion Flutter Pdf Viewer by the numbers
- 1 all-time installs (skills.sh)
- Ranked #959 of 1,039 Mobile Development skills by installs in the Skillselion catalog
- Data as of Jul 8, 2026 (Skillselion catalog sync)
npx skills add https://github.com/syncfusion/pdf-viewer-sdk-skills --skill syncfusion-flutter-pdf-viewerAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 1 |
|---|---|
| repo stars | ★ 1 |
| Last updated | July 6, 2026 |
| Repository | syncfusion/pdf-viewer-sdk-skills ↗ |
What it does
Scaffolds a Flutter project and generates Dart code to embed and configure the Syncfusion SfPdfViewer widget for loading PDF documents.
Files
Syncfusion Flutter SfPdfViewer – UI Sample Generator
Generate Dart Code for the User's Project (default)
Trigger keywords: "how to", "add pdfviewer", "code sample", "show me", "example", "snippet", "integrate", "widget", "create sample", "flutter pdfviewer".
Purpose: Scaffold a ready-to-run Flutter project with syncfusion_flutter_pdfviewer integrated and generate the requested feature code inside it — all in one pass.
Workflow:
Step 1 – Ask Clarifying Questions (once, upfront)
Before doing anything else, ask the user: 1. Project target: Does a Flutter project already exist, or should a new one be created? 2. File placement: Should the generated code go into an existing file (e.g., main.dart) or a new Dart file (e.g., pdf_viewer_sample.dart)? 3. Platform: Is the app targeting mobile, desktop, or web? (Only needed to decide whether the web `index.html` step is required.)
Step 2 – Create a New Flutter Project (skip if project already exists)
Run in the terminal:
flutter create pdf_viewer_app
cd pdf_viewer_appStep 3 – Add the Syncfusion Dependency (skip if already present in `pubspec.yaml`)
Add under dependencies in pubspec.yaml:
dependencies:
flutter:
sdk: flutter
syncfusion_flutter_pdfviewer: ^33.2.8Then run:
flutter pub getNotes:
- Use the latest stable version of the package from pub.dev.
Step 4 – (Web only) Update web/index.html
If the target platform is web, add the PdfJs script inside the <body> tag of web/index.html:
<script type="module" async>
import * as pdfjsLib from 'https://cdnjs.cloudflare.com/ajax/libs/pdf.js/4.10.38/pdf.min.mjs';
pdfjsLib.GlobalWorkerOptions.workerSrc = "https://cdnjs.cloudflare.com/ajax/libs/pdf.js/4.10.38/pdf.worker.min.mjs";
</script>Step 5 – Build and Write the Dart Code
1. Start with references/basic-sample.md as the base template. 2. Identify the feature(s) requested and merge the relevant snippets from references/*.md into the base. 3. Follow these code-generation rules:
- Use code exactly as shown in the reference — do not alter API usage.
- Add only the APIs required by the request; do not include extras.
- Always initialise
PdfViewerControllerininitState()when controller-based APIs are used.
4. Write the final code to the file chosen in Step 1:
- Existing file (e.g.,
main.dart): use the edit tool to insert or replace code. - New Dart file (e.g.,
pdf_viewer_sample.dart): use the create file tool to create it. - Never display the code only as a code block — always write it to the file using the appropriate tool.
Step 6 – Run the App
flutter run---
Code References
All templates and operation snippets live in references/*.md. Each file is a focused snippet or template the agent will combine when generating samples.
Flow: Always start with references/basic-sample.md, then merge matched features into its structure. If no keyword matches, return only the basic sample.
| File | Purpose |
|---|---|
| basic-sample.md | Minimal SfPdfViewer with a network/asset URL, Scaffold, and AppBar. |
| magnification.md | Configure zoom level, max zoom, double-tap zoom, and zoom callbacks using PdfViewerController and widget properties. |
| page-navigation.md | Navigate pages programmatically using jumpToPage, nextPage, previousPage, firstPage, lastPage, and jumpTo offset methods. |
| text-search.md | Search text, navigate results with nextInstance/previousInstance, cancel search, and customise highlight colors. |
| text-selection.md | Enable/disable text selection, customise selection color, handle onTextSelectionChanged callback. |
| bookmark-navigation.md | Open the built-in bookmark view and navigate to bookmarks programmatically using jumpToBookmark. |
| scrolling.md | Programmatic scrolling using jumpTo and reading current scroll offset via scrollOffset. |
| pdfviewer-properties.md | Common SfPdfViewer widget properties reference: canShowScrollHead, canShowPaginationDialog, interactionMode, pageLayoutMode, initialZoomLevel, onDocumentLoaded, onDocumentLoadFailed, onPageChanged, etc. |
| annotation.md | Add, remove, select, and manage text markup (Highlight, Underline, Strikethrough, Squiggly) and Sticky Note annotations using PdfViewerController methods and annotation callbacks. |
| signaturepad.md | Hide the built-in signature pad using canShowSignaturePadDialog and display a custom SfSignaturePad dialog via onFormFieldFocusChange to capture and assign drawn signatures to PdfSignatureFormField. |
| password-protected-pdf.md | Open encrypted PDF documents using the password property and handle load failures with onDocumentLoadFailed. |
| link-navigation.md | Enable/disable document link annotation navigation with enableDocumentLinkAnnotation and handle hyperlink taps using onHyperlinkClicked. |
| form-filling.md | Fill, edit, save, export, import, and clear AcroForm fields (text box, checkbox, radio button, combo box, list box, signature) using PdfViewerController methods and form field callbacks. |
| localization.md | Localize SfPdfViewer static UI text to any supported language using flutter_localizations, syncfusion_localizations, and MaterialApp locale configuration. |
| directionality.md | Enable right-to-left (RTL) rendering by wrapping SfPdfViewer with the Directionality widget or setting an RTL locale in MaterialApp. |
| accessibility.md | Make SfPdfViewer accessible via Semantics widget for screen readers, keyboard navigation shortcuts, large font support, and touch target standards. |
| gesture-callback.md | Handle tap gestures on the PDF viewer using the onTap callback and PdfGestureDetails (page number, page position, widget position). |
---
Syncfusion Flutter PdfViewer skill
Overview
Create Flutter applications featuring the Syncfusion Flutter SfPdfViewer, customized to meet specific user requirements.
See [SKILL.md](SKILL.md) for the full intent-routing guide and rules.
---
Key Capabilities
- High-fidelity PDF rendering & navigation: PDF viewing, bookmark navigation, hyperlink navigation, page navigation, scrolling, and magnification.
- Text search & selection: Search text, navigate results, and customise highlight colors; enable/disable text selection with custom selection color.
- Annotation support: Add, remove, select, and manage text markup (Highlight, Underline, Strikethrough, Squiggly) and Sticky Note annotations.
- Form filling: Fill, edit, save, export, import, and clear AcroForm fields (text box, checkbox, radio button, combo box, list box, signature).
- Accessibility & localization: Screen reader support, RTL rendering, and localization into any supported language.
---
Getting Started
How to Integrate Skills
Step 1: Checkout and copy the required skills
Clone or download the PDF-Viewer-SDK-Skills repository and copy the flutter-pdfviewer-code-generator skill from the skills/ directory.
Step 2: Install the skill
Place the copied skill folders in your workspace following this structure:
your-workspace/
├── .github/skills/ # or .claude/skills/ or .codestudio/skills/
│ └── flutter-pdfviewer-code-generator/
│ └── SKILL.md
├── your-project-files...
└── lib/main.dartStep 3: Verify and manage your skills
Type /skills in the GitHub Copilot or Code Studio chat to quickly access the Configure Skills menu and manage your installed skills.
Step 4: Use skills in VS Code
There are two ways to use skills:
1. Slash commands - Type / in the GitHub Copilot chat to see available skills.
2. Automatic loading - Simply describe your task naturally, and your AI Agent automatically loads the relevant skill:
Create a Flutter app with SfPdfViewer that loads a PDF document from a URLWhen the flutter-pdfviewer-code-generator skill is loaded, the AI Agent provides focused Dart snippets and commands for Syncfusion Flutter SfPdfViewer.
Prerequisites
- Flutter 3.x or later
- Dart 3.x or later
pub.dev Packages
flutter pub add syncfusion_flutter_pdfviewer---
Example Prompts
Code Generation
Use these when you want Dart code for your existing Flutter project.
- "Create a Flutter app that adds a Syncfusion SfPdfViewer, loads a PDF from a network URL, and shows zoom controls."
- "Add code to search for text inside the PDF and navigate between search results."
- "Show how to navigate to a specific page programmatically using PdfViewerController."
- "Add annotation support to highlight and underline text in the PDF."
- "Show how to fill and save AcroForm fields in a PDF document."
- "Enable RTL layout for the SfPdfViewer widget."
- "Add localization support for the SfPdfViewer UI in French."
---
Code References
All templates and operation snippets live in references/*.md. Each file is a focused snippet the agent combines when generating samples.
| File | Purpose |
|---|---|
| basic-sample.md | Minimal SfPdfViewer with a network/asset URL, Scaffold, and AppBar. |
| magnification.md | Configure zoom level, max zoom, double-tap zoom, and zoom callbacks. |
| page-navigation.md | Navigate pages programmatically using controller methods. |
| text-search.md | Search text, navigate results, and customise highlight colors. |
| text-selection.md | Enable/disable text selection and handle selection callbacks. |
| bookmark-navigation.md | Open the built-in bookmark view and navigate programmatically. |
| scrolling.md | Programmatic scrolling and reading current scroll offset. |
| pdfviewer-properties.md | Common SfPdfViewer widget properties reference. |
| annotation.md | Add, remove, and manage text markup and Sticky Note annotations. |
| signaturepad.md | Custom signature pad dialog integration with form fields. |
| password-protected-pdf.md | Open encrypted PDFs using the password property. |
| link-navigation.md | Enable document link navigation and handle hyperlink taps. |
| form-filling.md | Fill, edit, save, export, import, and clear AcroForm fields. |
| localization.md | Localize SfPdfViewer static UI text to any supported language. |
| directionality.md | Enable RTL rendering using Directionality widget or RTL locale. |
| accessibility.md | Make SfPdfViewer accessible via Semantics and keyboard navigation. |
| gesture-callback.md | Handle tap gestures using the onTap callback. |
---
Troubleshooting
| Issue | Solution |
|---|---|
| Missing package | Run flutter pub add syncfusion_flutter_pdfviewer |
| PDF not loading from network | Ensure internet permission is added in AndroidManifest.xml and Info.plist |
| PDF not loading from assets | Declare the asset path in pubspec.yaml under flutter: assets: |
---
Resources
---
Accessibility in Flutter SfPdfViewer
The SfPdfViewer is designed with accessibility in mind — it supports screen readers via the Semantics widget, adapts to large font settings, provides keyboard navigation shortcuts, and meets touch target standards.
---
Add a Screen Reader Support
Semantics(
label: 'Flutter PDF Viewer',
child: SfPdfViewer.network(
'https://cdn.syncfusion.com/content/PDFViewer/flutter-succinctly.pdf',
),
)---
Add a Sufficient Contrast
- Customize search highlight colors for readability.
SfPdfViewer.network(
'https://cdn.syncfusion.com/content/PDFViewer/flutter-succinctly.pdf',
controller: _pdfViewerController,
currentSearchTextHighlightColor: Colors.blue,
otherSearchTextHighlightColor: Colors.yellow,
)- Customize text selection colors.
MaterialApp(
theme: ThemeData(
textSelectionTheme: TextSelectionThemeData(
selectionColor: Colors.red, selectionHandleColor: Colors.blue),
),
home: HomePage(),
)---
Change the font size of the SfPdfViewer elements
paginationDialogStyle
SfTheme(
data: SfThemeData(
pdfViewerThemeData: SfPdfViewerThemeData(
paginationDialogStyle: PdfPaginationDialogStyle(
backgroundColor: Colors.black,
headerTextStyle: TextStyle(color: Colors.white)
inputFieldTextStyle: TextStyle(color: Colors.white)
hintTextStyle: TextStyle(color: Colors.grey)
pageInfoTextStyle: TextStyle(color: Colors.grey)
validationTextStyle: TextStyle(color: Colors.red)
okTextStyle: TextStyle(color: Colors.white)
cancelTextStyle: TextStyle(color: Colors.white)
)
)
),
child: SfPdfViewer.asset(
'assets/flutter-succinctly.pdf',
),
)bookmarkViewStyle
SfTheme(
data: SfThemeData(
pdfViewerThemeData: SfPdfViewerThemeData(
bookmarkViewStyle: PdfBookmarkViewStyle(
backgroundColor: Colors.black,
headerBarColor: Colors.grey,
closeIconColor: Colors.white,
backIconColor: Colors.white,
navigationIconColor: Colors.white,
selectionColor: Colors.grey,
titleSeparatorColor: Colors.grey,
titleTextStyle: TextStyle(color: Colors.white)
headerTextStyle: TextStyle(color: Colors.white)
)
)
),
child: SfPdfViewer.asset(
'assets/flutter-succinctly.pdf',
),
)scrollHeadStyle
SfTheme(
data: SfThemeData(
pdfViewerThemeData: SfPdfViewerThemeData(
scrollHeadStyle: PdfScrollHeadStyle(
backgroundColor: Colors.black,
headerTextStyle: TextStyle(color: Colors.white)
)
)
),
child: SfPdfViewer.asset(
'assets/flutter-succinctly.pdf',
),
)scrollStatusStyle
SfTheme(
data: SfThemeData(
pdfViewerThemeData: SfPdfViewerThemeData(
scrollStatusStyle: PdfScrollStatusStyle(
backgroundColor: Colors.grey,
pageInfoTextStyle: TextStyle(color: Colors.white)
)
)
),
child: SfPdfViewer.asset(
'assets/flutter-succinctly.pdf',
),
)---
Keyboard Navigation
Page Navigation
| Action | Windows / Linux | macOS |
|---|---|---|
| Navigate to the first page | Home | Fn + Left Arrow |
| Navigate to the last page | End | Fn + Right Arrow |
| Navigate to the previous page | Left Arrow | Left Arrow |
| Navigate to the next page | Right Arrow | Right Arrow |
Zooming
| Action | Windows / Linux | macOS |
|---|---|---|
| Zoom in | Ctrl + = | Cmd + = |
| Zoom out | Ctrl + - | Cmd + - |
| Reset zoom to 1.0 | Ctrl + 0 | Cmd + 0 |
Text Search
| Action | Windows / Linux | macOS |
|---|---|---|
| Open search toolbar | Ctrl + F | Cmd + F |
Text Selection
| Action | Windows / Linux | macOS |
|---|---|---|
| Copy selected text | Ctrl + C | Cmd + C |
---
Touch Targets
All interactive elements in SfPdfViewer follow the standard minimum touch target size of 48 × 48 dp, in accordance with platform accessibility guidelines.
---
Accessibility Reference
| Feature | API / Approach | Description |
|---|---|---|
| Screen Reader | Semantics widget wrapping SfPdfViewer | Provides a semantic label for assistive technologies. |
| Search contrast | currentSearchTextHighlightColor, otherSearchTextHighlightColor | Customize search highlight colors for visibility. |
| Selection contrast | TextSelectionThemeData.selectionColor | Customize text selection color for visibility. |
| Font scaling | Device accessibility settings | Font size in viewer UI scales automatically. |
| Custom font sizes | SfPdfViewerThemeData styles | Customize individual UI element font sizes. |
| Touch target size | Built-in | All interactive elements are 48 × 48 dp minimum. |
Annotations in Flutter SfPdfViewer
The SfPdfViewer allows you to add, remove, select, deselect, and programmatically manage annotations in a PDF document. Supported annotation types include text markup (Highlight, Underline, Strikethrough, Squiggly) and Sticky Note annotations.
---
Add a Text Markup Annotation via Annotation Mode
final PdfViewerController _pdfViewerController = PdfViewerController();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Flutter PDF Viewer'),
actions: <Widget>[
IconButton(
icon: const Icon(Icons.highlight, color: Colors.white),
onPressed: () {
_pdfViewerController.annotationMode = PdfAnnotationMode.highlight;
},
),
IconButton(
icon: const Icon(Icons.close, color: Colors.white),
onPressed: () {
_pdfViewerController.annotationMode = PdfAnnotationMode.none;
},
),
],
),
body: SfPdfViewer.network(
'https://cdn.syncfusion.com/content/PDFViewer/flutter-succinctly.pdf',
controller: _pdfViewerController,
),
);
}Note: SetannotationModetoPdfAnnotationMode.noneto exit annotation mode.
---
Add a Text Markup Annotation Programmatically
final GlobalKey<SfPdfViewerState> _pdfViewerKey = GlobalKey();
final PdfViewerController _pdfViewerController = PdfViewerController();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Flutter PDF Viewer'),
actions: <Widget>[
IconButton(
icon: const Icon(Icons.highlight),
onPressed: () {
final List<PdfTextLine>? selectedLines =
_pdfViewerKey.currentState?.getSelectedTextLines();
if (selectedLines != null && selectedLines.isNotEmpty) {
_pdfViewerController.addAnnotation(
HighlightAnnotation(textBoundsCollection: selectedLines),
);
}
},
),
],
),
body: SfPdfViewer.asset(
'assets/sample.pdf',
key: _pdfViewerKey,
controller: _pdfViewerController,
),
);
}---
Add a Sticky Note Annotation Programmatically
_pdfViewerController.addAnnotation(
StickyNoteAnnotation(
pageNumber: 2,
text: 'This is a sticky note',
icon: PdfStickyNoteIcon.comment,
position: const Offset(100, 150),
),
);---
Remove an Annotation Programmatically
// Remove a specific annotation
_pdfViewerController.removeAnnotation(annotation);
// Remove all annotations in the document
_pdfViewerController.removeAllAnnotations();
// Remove all annotations on page 2
_pdfViewerController.removeAllAnnotations(pageNumber: 2);---
Get All Annotations
final List<Annotation> annotations = _pdfViewerController.getAnnotations();
for (final Annotation annotation in annotations) {
print('Annotation type: ${annotation.runtimeType} on page ${annotation.pageNumber}');
}---
Annotation Settings
// Global defaults before adding annotations
_pdfViewerController.annotationSettings.author = 'Annotation';
_pdfViewerController.annotationSettings = PdfAnnotationSettings();
_pdfViewerController.annotationSettings.highlight = PdfTextMarkupAnnotationSettings();
_pdfViewerController.annotationSettings.selector = PdfAnnotationSelectorSettings();
_pdfViewerController.annotationSettings.squiggly = PdfTextMarkupAnnotationSettings();
_pdfViewerController.annotationSettings.stickyNote = PdfStickyNoteAnnotationSettings();
_pdfViewerController.annotationSettings.underline = PdfTextMarkupAnnotationSettings();
_pdfViewerController.annotationSettings.isLocked = false;
_pdfViewerController.annotationSettings.highlight.opacity = 0.8; = 0.8;
_pdfViewerController.annotationSettings.stickyNote.color = Colors.orange;
_pdfViewerController.annotationSettings.stickyNote.icon = PdfStickyNoteIcon.comment;---
Select and Deselect an Annotation Programmatically
// Select an annotation
_pdfViewerController.selectAnnotation(annotation);
// Deselect an annotation
_pdfViewerController.deselectAnnotation(annotation);---
Add an Annotation Callbacks
onAnnotationAdded
SfPdfViewer.network(
'https://cdn.syncfusion.com/content/PDFViewer/flutter-succinctly.pdf',
controller: _pdfViewerController,
onAnnotationAdded: (Annotation annotation) {
print('Annotation added on page ${annotation.pageNumber}');
},
)onAnnotationSelected
SfPdfViewer.network(
'https://cdn.syncfusion.com/content/PDFViewer/flutter-succinctly.pdf',
controller: _pdfViewerController,
onAnnotationSelected: (Annotation annotation) {
print('Annotation selected: ${annotation.runtimeType}');
},
)onAnnotationDeselected
SfPdfViewer.network(
'https://cdn.syncfusion.com/content/PDFViewer/flutter-succinctly.pdf',
controller: _pdfViewerController,
onAnnotationDeselected: (Annotation annotation) {
print('Annotation deselected');
},
)onAnnotationEdited
SfPdfViewer.network(
'https://cdn.syncfusion.com/content/PDFViewer/flutter-succinctly.pdf',
controller: _pdfViewerController,
onAnnotationEdited: (Annotation annotation) {
print('Annotation edited');
},
)onAnnotationRemoved
SfPdfViewer.network(
'https://cdn.syncfusion.com/content/PDFViewer/flutter-succinctly.pdf',
controller: _pdfViewerController,
onAnnotationRemoved: (Annotation annotation) {
print('Annotation removed from page ${annotation.pageNumber}');
},
)---
Add an Undo and Redo Annotation Actions
final UndoHistoryController _undoController = UndoHistoryController();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
actions: [
ValueListenableBuilder(
valueListenable: _undoController,
builder: (context, value, child) {
return IconButton(
onPressed: _undoController.value.canUndo ? _undoController.undo : null,
icon: const Icon(Icons.undo),
);
},
),
ValueListenableBuilder(
valueListenable: _undoController,
builder: (context, value, child) {
return IconButton(
onPressed: _undoController.value.canRedo ? _undoController.redo : null,
icon: const Icon(Icons.redo),
);
},
),
],
),
body: SfPdfViewer.asset(
'assets/sample.pdf',
undoController: _undoController,
),
);
}Note: undoController is shared between annotations and form fields — a single instance handles both.---
Get Annotation Details Programmatically
SfPdfViewer.asset(
'assets/sample.pdf',
onAnnotationAdded: (Annotation annotation) {
print('Author of the annotation: ${annotation.author}');
print('Color of the annotation: ${annotation.color}');
print('State of the annotation: ${annotation.isLocked}');
print('Name of the annotation: ${annotation.name}');
print('Opacity of the Annotation: ${annotation.opacity}');
print('Subject of the annotation: ${annotation.subject}');
},
),---
Annotation Properties and Methods Reference
PdfViewerController Annotation Methods
| Method/Property | Description |
|---|---|
annotationMode | Gets or sets the active annotation mode (PdfAnnotationMode). |
annotationSettings | Gets or sets default appearance settings for annotations. |
addAnnotation(Annotation) | Adds the given annotation to its specified page. |
removeAnnotation(Annotation) | Removes the specified annotation. |
removeAllAnnotations({int pageNumber = 0}) | Removes all annotations; pageNumber: 0 removes from entire document. |
getAnnotations() | Returns a List<Annotation> of all annotations in the PDF. |
selectAnnotation(Annotation) | Programmatically selects the given annotation. |
deselectAnnotation(Annotation) | Programmatically deselects the given annotation. |
PdfAnnotationMode Enum
| Value | Description |
|---|---|
PdfAnnotationMode.none | No annotation mode active (default). |
PdfAnnotationMode.highlight | Activates highlight annotation mode. |
PdfAnnotationMode.underline | Activates underline annotation mode. |
PdfAnnotationMode.strikethrough | Activates strikethrough annotation mode. |
PdfAnnotationMode.squiggly | Activates squiggly annotation mode. |
PdfAnnotationMode.stickyNote | Activates stickynote annotation mode. |
Annotation Classes
| Class | Description |
|---|---|
HighlightAnnotation | Text markup highlight annotation. Requires textBoundsCollection. |
UnderlineAnnotation | Text markup underline annotation. Requires textBoundsCollection. |
StrikethroughAnnotation | Text markup strikethrough annotation. Requires textBoundsCollection. |
SquigglyAnnotation | Text markup squiggly annotation. Requires textBoundsCollection. |
StickyNoteAnnotation | Sticky note annotation. Requires pageNumber, position, and text. |
StickyNoteAnnotation Properties
| Property | Description | Type |
|---|---|---|
pageNumber | The page number where the annotation is placed (1-based). | int |
text | The content of the sticky note. | String |
icon | The icon style of the sticky note. | PdfStickyNoteIcon |
position | The position of the annotation on the page in PDF coordinates. | Offset |
PdfStickyNoteIcon Enum
| Value | Description |
|---|---|
PdfStickyNoteIcon.comment | Comment icon (default). |
PdfStickyNoteIcon.note | Note icon. |
PdfStickyNoteIcon.help | Help icon. |
PdfStickyNoteIcon.insert | Insert icon. |
PdfStickyNoteIcon.key | Key icon. |
PdfStickyNoteIcon.newParagraph | New paragraph icon. |
PdfStickyNoteIcon.paragraph | Paragraph icon. |
SfPdfViewer Annotation Callbacks
| Callback | Description | Details Object |
|---|---|---|
onAnnotationAdded | Triggered when an annotation is added. | Annotation |
onAnnotationSelected | Triggered when an annotation is selected. | Annotation |
onAnnotationDeselected | Triggered when an annotation is deselected. | Annotation |
onAnnotationEdited | Triggered when an annotation is edited. | Annotation |
onAnnotationRemoved | Triggered when an annotation is removed. | Annotation |
Basic Flutter SfPdfViewer Sample (foundation)
This is the only file that renders the page layout. All features are built on top of this sample.
Check Dependency Setup
Add to pubspec.yaml:
dependencies:
syncfusion_flutter_pdfviewer: ^33.2.8Run:
flutter pub getNotes:
- Use the latest stable version of the package from pub.dev.
Import
import 'package:syncfusion_flutter_pdfviewer/pdfviewer.dart';Load from Network URL
import 'package:flutter/material.dart';
import 'package:syncfusion_flutter_pdfviewer/pdfviewer.dart';
void main() {
runApp(const MaterialApp(
home: PdfViewerPage(),
));
}
class PdfViewerPage extends StatefulWidget {
const PdfViewerPage({super.key});
@override
State<PdfViewerPage> createState() => _PdfViewerPageState();
}
class _PdfViewerPageState extends State<PdfViewerPage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Flutter PDF Viewer'),
),
body: SfPdfViewer.network(
'https://cdn.syncfusion.com/content/PDFViewer/flutter-succinctly.pdf',
onDocumentLoaded: (PdfDocumentLoadedDetails details) {
print('Document loaded: ${details.document.pages.count} pages');
},
onDocumentLoadFailed: (PdfDocumentLoadFailedDetails details) {
print('Load failed - Error: ${details.error}');
print('Description: ${details.description}');
},
),
);
}
}Load from Assets
@override
Widget build(BuildContext context) {
return Scaffold(
body: SfPdfViewer.asset('assets/sample.pdf'),
);
}Note: Add the asset path topubspec.yamlunder theflutter > assetssection.
Load from File System
import 'dart:io';
@override
Widget build(BuildContext context) {
return Scaffold(
body: SfPdfViewer.file(File('/path/to/document.pdf')),
);
}Load from Memory
@override
Widget build(BuildContext context) {
return Scaffold(
body: SfPdfViewer.memory(bytes),
);
}Document Source Access
// Via unified PDFSource abstraction
SfPdfViewer(source: AssetPDFSource('assets/document.pdf'));
SfPdfViewer(source: URLPDFSource('https://example.com/doc.pdf'));
SfPdfViewer(source: BytePDFSource(bytes));
SfPdfViewer(source: FilePDFSource(file));Add Web Platform Setup
For the web platform, add the following to web/index.html (PdfJs 4.0+):
<script type="module" async>
import * as pdfjsLib from 'https://cdnjs.cloudflare.com/ajax/libs/pdf.js/4.10.38/pdf.min.mjs';
pdfjsLib.GlobalWorkerOptions.workerSrc = "https://cdnjs.cloudflare.com/ajax/libs/pdf.js/4.10.38/pdf.worker.min.mjs";
</script>Bookmark Navigation in Flutter SfPdfViewer
Navigate to desired bookmark topics using the built-in bookmark view or programmatically using PdfViewerController. The built-in bookmark panel displays all bookmarks saved in the PDF document.
Note: Import'package:syncfusion_flutter_pdf/pdf.dart'to usePdfBookmark.
---
Open the Built-in Bookmark View Programmatically
final GlobalKey<SfPdfViewerState> _pdfViewerKey = GlobalKey();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Flutter PDF Viewer'),
actions: <Widget>[
IconButton(
icon: const Icon(Icons.bookmark, color: Colors.white),
onPressed: () {
_pdfViewerKey.currentState?.openBookmarkView();
},
),
],
),
body: SfPdfViewer.network(
'https://cdn.syncfusion.com/content/PDFViewer/flutter-succinctly.pdf',
key: _pdfViewerKey,
),
);
}---
Check if Bookmark View is Open
IconButton(
icon: const Icon(Icons.help_outline),
onPressed: () {
if (_pdfViewerKey.currentState?.isBookmarkViewOpen ?? false) {
print('Bookmark view is open.');
} else {
print('Bookmark view is closed.');
}
},
),---
Navigate to a Specific Bookmark Programmatically
final PdfViewerController _pdfViewerController = PdfViewerController();
late PdfBookmark _pdfBookmark;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Flutter PDF Viewer'),
actions: <Widget>[
IconButton(
icon: const Icon(Icons.arrow_drop_down_circle, color: Colors.white),
onPressed: () {
_pdfViewerController.jumpToBookmark(_pdfBookmark);
},
),
],
),
body: SfPdfViewer.network(
'https://cdn.syncfusion.com/content/PDFViewer/flutter-succinctly.pdf',
controller: _pdfViewerController,
onDocumentLoaded: (PdfDocumentLoadedDetails details) {
_pdfBookmark = details.document.bookmarks[0];
},
),
);
}---
Bookmark Navigation Reference
SfPdfViewerState Methods and Properties
| API | Description | Type |
|---|---|---|
openBookmarkView() | Opens the built-in bookmark panel. | Method |
isBookmarkViewOpen | Returns true if the bookmark panel is currently open. | bool property |
PdfViewerController Methods
| Method | Description |
|---|---|
jumpToBookmark(PdfBookmark bookmark) | Navigates the viewer to the position of the given bookmark. |
onDocumentLoaded Callback
The onDocumentLoaded callback provides a PdfDocumentLoadedDetails object with the loaded PdfDocument, which exposes the bookmarks collection.
| Property | Description | Type |
|---|---|---|
details.document | The loaded PdfDocument instance. | PdfDocument |
details.document.bookmarks | Collection of PdfBookmark objects in the document. | PdfBookmarkBase |
Add Directionality (RTL) in Flutter SfPdfViewer
The SfPdfViewer supports right-to-left (RTL) rendering. All UI elements, text search, and text copying adapt to the configured text direction. RTL can be enabled in two ways: wrapping SfPdfViewer with the Directionality widget, or changing the MaterialApp locale to an RTL language.
Note: RTL scrolling is not supported in single-page layout mode whenscrollDirectionis set toPdfScrollDirection.horizontal.
---
Method 1: Wrap with Directionality Widget
final GlobalKey<SfPdfViewerState> _pdfViewerKey = GlobalKey();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Flutter PDF Viewer'),
actions: <Widget>[
IconButton(
icon: const Icon(
Icons.bookmark,
color: Colors.white,
semanticLabel: 'Bookmark',
),
onPressed: () {
_pdfViewerKey.currentState?.openBookmarkView();
},
),
],
),
body: Directionality(
textDirection: TextDirection.rtl,
child: SfPdfViewer.network(
'https://cdn.syncfusion.com/content/PDFViewer/flutter-succinctly.pdf',
key: _pdfViewerKey,
),
),
);
}---
Method 2: Change Locale to an RTL Language
Add to pubspec.yaml:
dependencies:
flutter_localizations:
sdk: flutterimport 'package:flutter_localizations/flutter_localizations.dart';
final GlobalKey<SfPdfViewerState> _pdfViewerKey = GlobalKey();
@override
Widget build(BuildContext context) {
return MaterialApp(
localizationsDelegates: const [
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
],
supportedLocales: const <Locale>[
Locale('en'),
Locale('ar'),
],
locale: const Locale('ar'),
home: Scaffold(
appBar: AppBar(
title: const Text('Flutter PDF Viewer'),
actions: <Widget>[
IconButton(
icon: const Icon(
Icons.bookmark,
color: Colors.white,
semanticLabel: 'Bookmark',
),
onPressed: () {
_pdfViewerKey.currentState?.openBookmarkView();
},
),
],
),
body: SfPdfViewer.network(
'https://cdn.syncfusion.com/content/PDFViewer/flutter-succinctly.pdf',
key: _pdfViewerKey,
),
),
);
}---
Directionality Properties Reference
| API | Description |
|---|---|
Directionality widget | Flutter framework widget. Wrap SfPdfViewer with textDirection: TextDirection.rtl to force RTL layout. |
textDirection | The text direction for the widget subtree. Use TextDirection.rtl for right-to-left. Use TextDirection.ltr for left-to-right. |
locale (MaterialApp) | Setting locale to an RTL language (e.g., Locale('ar')) automatically switches the viewer to RTL mode. |
Form Filling in Flutter SfPdfViewer
The SfPdfViewer allows you to fill, edit, save, export, and import AcroForm fields in a PDF document. Supported form field types are: text box, checkbox, radio button, combo box, list box, and signature.
---
Get Form Fields
final PdfViewerController _pdfViewerController = PdfViewerController();
final List<PdfFormField> formFields = _pdfViewerController.getFormFields();Fetch and read the form field details.
final List<PdfFormField> formFields = _pdfViewerController.getFormFields();
for (final PdfFormField field in formFields) {
print('Field Name : ${field.name}');
print('Page Number : ${field.pageNumber}');
print('Read Only : ${field.isReadOnly}');;
}---
Edit Form Fields Programmatically
Edit Text Box
final List<PdfFormField> formFields = _pdfViewerController.getFormFields();
final PdfTextFormField textbox = formFields.singleWhere(
(PdfFormField f) => f.name == 'name') as PdfTextFormField;
textbox.text = 'John';Edit Checkbox
final PdfCheckboxFormField checkbox = formFields.singleWhere(
(PdfFormField f) => f.name == 'newsletter') as PdfCheckboxFormField;
checkbox.isChecked = true;Edit Combo Box
final PdfComboBoxFormField combobox = formFields.singleWhere(
(PdfFormField f) => f.name == 'state') as PdfComboBoxFormField;
combobox.selectedItem = combobox.items[4];Edit Radio Button
final PdfRadioFormField radiobutton = formFields.singleWhere(
(PdfFormField f) => f.name == 'gender') as PdfRadioFormField;
radiobutton.selectedItem = radiobutton.items[2];Edit List Box
final PdfListBoxFormField listbox = formFields.singleWhere(
(PdfFormField f) => f.name == 'list') as PdfListBoxFormField;
listbox.selectedItems = listbox.items.sublist(0, 2);Edit Signature
final PdfSignatureFormField signature = formFields.singleWhere(
(PdfFormField f) => f.name == 'signature') as PdfSignatureFormField;
final ByteData bytedata = await rootBundle.load('assets/signature.png');
signature.signature = bytedata.buffer.asUint8List();---
Restrict Editing of Form Fields
final List<PdfFormField> formFields = _pdfViewerController.getFormFields();
formFields[0].readOnly = true;---
Clear Form Data
// Clear all form field data in the document
_pdfViewerController.clearFormData();
// Clear all form field data on page 2
_pdfViewerController.clearFormData(pageNumber: 2);---
Save Form Data
final List<int> savedBytes = await _pdfViewerController.saveDocument();Flatten Form Fields on Save
final List<int> savedBytes = await _pdfViewerController.saveDocument(
flattenOption: PdfFlattenOption.formFields,
);---
Export Form Data
Note: Import'package:syncfusion_flutter_pdf/pdf.dart'for theDataFormatenum.
final List<int> formDataBytes = _pdfViewerController.exportFormData(
dataFormat: DataFormat.xfdf,
);Supported formats: DataFormat.fdf, DataFormat.xfdf, DataFormat.json, DataFormat.xml.
---
Import Form Data
final ByteData data = await DefaultAssetBundle.of(context).load('assets/form_data.xfdf');
final List<int> formDataBytes = data.buffer.asUint8List();
_pdfViewerController.importFormData(formDataBytes, DataFormat.xfdf);Pass continueImportOnError: true to skip fields that error during import.
---
Add an Undo and Redo Actions For Form Field Changes
final UndoHistoryController _undoController = UndoHistoryController();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
actions: [
ValueListenableBuilder(
valueListenable: _undoController,
builder: (context, value, child) {
return IconButton(
onPressed: _undoController.value.canUndo ? _undoController.undo : null,
icon: const Icon(Icons.undo),
);
},
),
ValueListenableBuilder(
valueListenable: _undoController,
builder: (context, value, child) {
return IconButton(
onPressed: _undoController.value.canRedo ? _undoController.redo : null,
icon: const Icon(Icons.redo),
);
},
),
],
),
body: SfPdfViewer.asset(
'assets/form_document.pdf',
undoController: _undoController,
),
);
}---
Add Form Field Callbacks
onFormFieldFocusChange
SfPdfViewer.asset(
'assets/form_document.pdf',
onFormFieldFocusChange: (PdfFormFieldFocusChangeDetails details) {
print('${details.formField.name} - hasFocus: ${details.hasFocus}');
},
)onFormFieldValueChanged
SfPdfViewer.asset(
'assets/form_document.pdf',
onFormFieldValueChanged: (PdfFormFieldValueChangedDetails details) {
print('Old: ${details.oldValue}');
print('New: ${details.newValue}');
},
)---
Customize Built-in Signature Pad Visibility
SfPdfViewer.asset(
'assets/form_document.pdf',
canShowSignaturePadDialog: false,
)---
Form Filling Properties and Methods Reference
PdfViewerController Methods
| Method | Description |
|---|---|
getFormFields() | Returns a List<PdfFormField> of all form fields in the document. |
clearFormData({int pageNumber = 0}) | Clears form field data. pageNumber: 0 clears all pages. |
saveDocument({PdfFlattenOption flattenOption}) | Saves the document and returns Future<List<int>>. |
exportFormData({required DataFormat dataFormat}) | Exports form data as bytes in the specified format. |
importFormData(List<int> inputBytes, DataFormat dataFormat, [bool continueImportOnError = false]) | Imports form data from bytes. |
Form Field Classes
| Class | Key Property | Description |
|---|---|---|
PdfTextFormField | text | Read/write text content. |
PdfCheckboxFormField | isChecked | Read/write checked state. |
PdfComboBoxFormField | selectedItem, items | Read/write selected combo box item. |
PdfRadioFormField | selectedItem, items | Read/write selected radio button item. |
PdfListBoxFormField | selectedItems, items | Read/write selected list box items. |
PdfSignatureFormField | signature | Read/write signature as Uint8List. Assign null to remove. |
PdfFormField (base) | name, readOnly | Common properties for all form fields. |
SfPdfViewer Form Filling Properties
| Property | Description | Type | Default |
|---|---|---|---|
canShowSignaturePadDialog | Shows or hides the built-in signature pad dialog. | bool | true |
undoController | Enables undo/redo for form fields and annotations. | UndoHistoryController? | — |
onFormFieldFocusChange | Callback when focus changes in a text box or signature field. | PdfFormFieldFocusChangeCallback? | — |
onFormFieldValueChanged | Callback when a form field value changes. | PdfFormFieldValueChangedCallback? | — |
PdfFlattenOption Enum
| Value | Description |
|---|---|
PdfFlattenOption.none | Form fields remain editable after saving (default). |
PdfFlattenOption.formFields | Form fields are flattened (non-editable) after saving. |
DataFormat Enum (from syncfusion_flutter_pdf)
| Value | Description |
|---|---|
DataFormat.fdf | FDF format. |
DataFormat.xfdf | XFDF format. |
DataFormat.json | JSON format. |
DataFormat.xml | XML format. |
Gesture Callbacks in Flutter SfPdfViewer
The SfPdfViewer supports the onTap gesture callback to notify touch or mouse interaction with the widget. The callback provides detailed position and page information via PdfGestureDetails.
---
Add onTap Callback
SfPdfViewer.network(
'https://cdn.syncfusion.com/content/PDFViewer/flutter-succinctly.pdf',
onTap: (PdfGestureDetails details) {
print('Page number: ${details.pageNumber}');
print('Page position: ${details.pagePosition}');
print('Widget position: ${details.position}');
},
)---
Gesture Callback Properties Reference
SfPdfViewer Gesture Callback
| Callback | Description | Details Object |
|---|---|---|
onTap | Triggered when the user taps or clicks on the SfPdfViewer widget. | PdfGestureDetails |
PdfGestureDetails Properties
| Property | Description | Type |
|---|---|---|
pageNumber | The page number where the tap occurred (1-based). -1 if outside any page. | int |
pagePosition | The tapped position in PDF page coordinates. (-1, -1) if outside any page. | Offset |
position | The tapped position in the viewer widget's coordinate space. | Offset |
Link Navigation in Flutter SfPdfViewer
The SfPdfViewer supports two types of link navigation:
1. Document Link Annotation Navigation – Navigate to a topic or position within the PDF by tapping document link annotations (e.g., table of contents links). 2. Hyperlink Navigation – Automatically detects hyperlinks in the PDF and opens them in the default web browser when tapped. ---
Document Link Annotation Navigation
Enable or Disable Document Link Annotation Navigation
SfPdfViewer.network(
'https://cdn.syncfusion.com/content/PDFViewer/flutter-succinctly.pdf',
enableDocumentLinkAnnotation: false,
)---
Hyperlink Navigation
Enable or Disable Hyperlink Navigation
SfPdfViewer.network(
'https://cdn.syncfusion.com/content/PDFViewer/flutter-succinctly.pdf',
enableHyperlinkNavigation: false,
)---
Handle Hyperlink Click Callback
SfPdfViewer.network(
'https://cdn.syncfusion.com/content/PDFViewer/flutter-succinctly.pdf',
onHyperlinkClicked: (PdfHyperlinkClickedDetails details) {
print('Hyperlink tapped: ${details.uri}');
},
)---
Link Navigation Properties Reference
| API | Description | Type | Default |
|---|---|---|---|
enableDocumentLinkAnnotation | Enables or disables document link annotation navigation (e.g., table of contents). | Widget property (bool) | true |
enableHyperlinkNavigation | Enables or disables hyperlink navigation | Widget property (bool) | true |
onHyperlinkClicked | Callback triggered when a hyperlink in the PDF is tapped. Returns PdfHyperlinkClickedDetails. | Widget callback |
PdfHyperlinkClickedDetails Properties
| Property | Description | Type |
|---|---|---|
uri | The URL string of the tapped hyperlink. | String |
Localization in Flutter SfPdfViewer
By default, SfPdfViewer uses US English localization. You can change the display language by specifying the MaterialApp locale properties and adding the flutter_localizations and syncfusion_localizations packages. This localizes static text in the PDF Viewer such as the page navigation dialog and bookmark view.
---
Chcek Dependency Setup
Add to pubspec.yaml:
dependencies:
flutter_localizations:
sdk: flutter
syncfusion_localizations: ^33.2.8Run:
flutter pub getNotes:
- Use the latest stable version of the package from pub.dev.
---
Apply Localization
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:syncfusion_localizations/syncfusion_localizations.dart';
@override
Widget build(BuildContext context) {
return MaterialApp(
localizationsDelegates: const [
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
SfGlobalLocalizations.delegate,
],
supportedLocales: const [
Locale('fr'),
Locale('ru'),
Locale('ta'),
],
locale: const Locale('fr'),
title: 'PDF Viewer Localization',
home: Scaffold(
appBar: AppBar(
title: const Text('Flutter PDF Viewer'),
),
body: SfPdfViewer.network(
'https://cdn.syncfusion.com/content/PDFViewer/flutter-succinctly.pdf',
),
),
);
}Note:SfGlobalLocalizations.delegateis required from thesyncfusion_localizationspackage to localize Syncfusion widget strings (e.g., pagination dialog labels, bookmark view text).
---
Localization Properties Reference
| API | Description |
|---|---|
localizationsDelegates | List of delegates providing localized resources. Must include GlobalMaterialLocalizations.delegate, GlobalWidgetsLocalizations.delegate, and SfGlobalLocalizations.delegate. |
supportedLocales | The list of Locale values the app supports. |
locale | The active locale for the app. Drives the language displayed in SfPdfViewer UI elements. |
Magnification in Flutter SfPdfViewer
The Flutter PDF Viewer allows zooming in and out either by pinch-to-zoom gesture or programmatically via PdfViewerController. Active viewport rendering is automatically enabled at zoom levels above 2.0 for better performance on large pages.
---
Change Zoom Level Programmatically
final PdfViewerController _pdfViewerController = PdfViewerController();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Flutter PDF Viewer'),
actions: <Widget>[
IconButton(
icon: const Icon(Icons.zoom_in, color: Colors.white),
onPressed: () {
_pdfViewerController.zoomLevel = 2;
},
),
IconButton(
icon: const Icon(Icons.zoom_out, color: Colors.white),
onPressed: () {
_pdfViewerController.zoomLevel = 1;
},
),
],
),
body: SfPdfViewer.network(
'https://cdn.syncfusion.com/content/PDFViewer/flutter-succinctly.pdf',
controller: _pdfViewerController,
),
);
}---
Set Maximum Zoom Level
SfPdfViewer.network(
'https://cdn.syncfusion.com/content/PDFViewer/flutter-succinctly.pdf',
maxZoomLevel: 5,
)---
Enable or Disable Double-Tap Zoom
SfPdfViewer.network(
'https://cdn.syncfusion.com/content/PDFViewer/flutter-succinctly.pdf',
enableDoubleTapZooming: false,
)Note: On desktop web browsers, enableDoubleTapZooming has no effect on mouse interaction.---
Add Zoom Level Changed Callback
SfPdfViewer.network(
'https://cdn.syncfusion.com/content/PDFViewer/flutter-succinctly.pdf',
onZoomLevelChanged: (PdfZoomDetails details) {
print('Old zoom: ${details.oldZoomLevel}');
print('New zoom: ${details.newZoomLevel}');
},
)---
Magnification Properties and Methods
| API Name | Description | Type | Default |
|---|---|---|---|
| zoomLevel | Gets or sets the current zoom level. Minimum value is 1.0. | PdfViewerController property | 1.0 |
| maxZoomLevel | Maximum zoom level allowed for the viewer. | Widget property | 3.0 |
| enableDoubleTapZooming | Enables or disables double-tap zoom gesture. | Widget property | true |
| onZoomLevelChanged | Callback triggered when zoom level changes. Returns PdfZoomDetails. | Widget callback | — |
PdfZoomDetails
| Property | Description | Type |
|---|---|---|
| oldZoomLevel | The zoom level before the change. | double |
| newZoomLevel | The zoom level after the change. | double |
Page Navigation in Flutter SfPdfViewer
Navigate to desired pages instantly using the built-in page navigation dialog or programmatically via PdfViewerController methods. If the target page does not exist, navigation will not occur and the current page is retained.
---
Navigate to a Specific Page
final PdfViewerController _pdfViewerController = PdfViewerController();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Flutter PDF Viewer'),
actions: <Widget>[
IconButton(
icon: const Icon(Icons.arrow_drop_down_circle, color: Colors.white),
onPressed: () {
_pdfViewerController.jumpToPage(5);
},
),
],
),
body: SfPdfViewer.network(
'https://cdn.syncfusion.com/content/PDFViewer/flutter-succinctly.pdf',
controller: _pdfViewerController,
),
);
}---
Navigate to Next and Previous Page
//Navigate to Previous Page
_pdfViewerController.previousPage();
//Navigate to Next Page
_pdfViewerController.nextPage();
---
Navigate to First and Last Page
//Navigate to First Page
_pdfViewerController.firstPage();
//Navigate to Last Page
_pdfViewerController.lastPage();---
Add Page Changed Callback
SfPdfViewer.network(
'https://cdn.syncfusion.com/content/PDFViewer/flutter-succinctly.pdf',
onPageChanged: (PdfPageChangedDetails details) {
print('Page changed to: ${details.newPageNumber}');
print('Is first page: ${details.isFirstPage}');
print('Is last page: ${details.isLastPage}');
},
)---
Navigation Methods and Callbacks Reference
PdfViewerController Methods
| Method | Description |
|---|---|
jumpToPage(int pageNumber) | Navigates to the specified page number. |
nextPage() | Navigates to the next page. |
previousPage() | Navigates to the previous page. |
firstPage() | Navigates to the first page. |
lastPage() | Navigates to the last page. |
jumpTo({double xOffset, double yOffset}) | Scrolls the viewer to the specified offset position. Both parameters are optional; defaults to (0, 0). |
PdfPageChangedDetails Properties
| Property | Description | Type |
|---|---|---|
| oldPageNumber | The page number before the change. | int |
| newPageNumber | The page number after the change. | int |
| isFirstPage | Whether the new page is the first page. | bool |
| isLastPage | Whether the new page is the last page. | bool |
Password-Protected PDF in Flutter SfPdfViewer
The SfPdfViewer supports opening password-protected (encrypted) PDF documents by passing the password via the password property. If the password is incorrect or missing, the onDocumentLoadFailed callback is triggered.
---
Open a Password-Protected PDF
SfPdfViewer.asset(
'assets/sample.pdf',
password: 'syncfusion',
)---
Handle Incorrect or Missing Password
SfPdfViewer.asset(
'assets/sample.pdf',
password: 'wrongpassword',
onDocumentLoadFailed: (PdfDocumentLoadFailedDetails details) {
print('Error: ${details.error}');
print('Description: ${details.description}');
},
)---
Show a Custom Password Dialog
String? _password;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Flutter PDF Viewer'),
),
body: SfPdfViewer.asset(
'assets/sample.pdf',
password: _password,
canShowPasswordDialog: false,
onDocumentLoadFailed: (PdfDocumentLoadFailedDetails details) {
if (details.error == 'Invalid cross reference table' ||
details.description.contains('password')) {
_showPasswordDialog();
}
},
),
);
}
Future<void> _showPasswordDialog() async {
final TextEditingController passwordController = TextEditingController();
await showDialog<void>(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: const Text('Password Required'),
content: TextField(
controller: passwordController,
obscureText: true,
decoration: const InputDecoration(labelText: 'Enter password'),
),
actions: <Widget>[
TextButton(
onPressed: () {
Navigator.of(context).pop();
setState(() {
_password = passwordController.text;
});
},
child: const Text('OK'),
),
],
);
},
);
}---
Password-Protected PDF Properties Reference
| API | Description | Type | Default |
|---|---|---|---|
password | The password to open an encrypted PDF document. | Widget property (String?) | null |
onDocumentLoadFailed | Callback triggered when the document fails to load (e.g., wrong/missing password). Returns PdfDocumentLoadFailedDetails. | Widget callback | — |
PdfDocumentLoadFailedDetails Properties
| Property | Description | Type |
|---|---|---|
error | A short error description (e.g., 'Invalid cross reference table'). | String |
description | A detailed description of the load failure. | String |
SfPdfViewer Widget Properties Reference
Common properties available on the SfPdfViewer widget for configuring behavior, appearance, and callbacks.
---
Add a Document Load Callbacks
onDocumentLoaded
SfPdfViewer.network(
'https://cdn.syncfusion.com/content/PDFViewer/flutter-succinctly.pdf',
onDocumentLoaded: (PdfDocumentLoadedDetails details) {
print('Document loaded: ${details.document.pages.count} pages');
},
)onDocumentLoadFailed
SfPdfViewer.network(
'https://example.com/invalid.pdf',
onDocumentLoadFailed: (PdfDocumentLoadFailedDetails details) {
print('Error: ${details.error}');
print('Description: ${details.description}');
},
)---
Get Page Count and Current Page number
SfPdfViewer.network(
'https://cdn.syncfusion.com/content/PDFViewer/flutter-succinctly.pdf',
onDocumentLoaded: (details) {
print('Page count: ${pdfViewerController.count}');
print('Current page cumber: ${pdfViewerController.pageNumber}');
},
)---
Add Interaction Mode
SfPdfViewer.network(
'https://cdn.syncfusion.com/content/PDFViewer/flutter-succinctly.pdf',
interactionMode: PdfInteractionMode.selection,
)---
Add Page Layout Mode
SfPdfViewer.network(
'https://cdn.syncfusion.com/content/PDFViewer/flutter-succinctly.pdf',
pageLayoutMode: PdfPageLayoutMode.single,
)---
Add Scroll Direction
SfPdfViewer.network(
'https://cdn.syncfusion.com/content/PDFViewer/flutter-succinctly.pdf',
scrollDirection: PdfScrollDirection.horizontal,
)---
Add Initial Zoom Level and Initial Page number
SfPdfViewer.network(
'https://cdn.syncfusion.com/content/PDFViewer/flutter-succinctly.pdf',
initialZoomLevel: 1.5,
initialPageNumber: 4,
)---
Show or Hide Scroll Head and Scroll Status
SfPdfViewer.network(
'https://cdn.syncfusion.com/content/PDFViewer/flutter-succinctly.pdf',
canShowScrollHead: false,
canShowScrollStatus: false,
)---
Show or Hide Pagination Dialog and Page Loading Indicator
SfPdfViewer.network(
'https://cdn.syncfusion.com/content/PDFViewer/flutter-succinctly.pdf',
canShowPaginationDialog: false,
canShowPageLoadingIndicator: false,
)---
Show or Hide Hyperlink Dialog
SfPdfViewer.network(
'https://cdn.syncfusion.com/content/PDFViewer/flutter-succinctly.pdf',
canShowHyperlinkDialog: false,
)---
Add Page spacing and Initial Scroll Offset
SfPdfViewer.network(
'https://cdn.syncfusion.com/content/PDFViewer/flutter-succinctly.pdf',
pageSpacing: 10,
initialScrollOffset: Offset(0, 600),
)---
Open Password-Protected Documents
SfPdfViewer.network(
'https://cdn.syncfusion.com/content/PDFViewer/encrypted.pdf',
password: 'syncfusion',
)---
SfPdfViewer Widget Properties Table
| Property | Description | Type | Default |
|---|---|---|---|
controller | The PdfViewerController instance for programmatic control. | PdfViewerController? | — |
initialZoomLevel | Sets the zoom level when the document is first loaded. | double | 1.0 |
maxZoomLevel | Maximum zoom level allowed. | double | 3.0 |
interactionMode | Sets the user interaction mode: selection or pan. | PdfInteractionMode | PdfInteractionMode.selection |
pageLayoutMode | Sets how pages are laid out: continuous or single. | PdfPageLayoutMode | PdfPageLayoutMode.continuous |
scrollDirection | Sets how pages are scrolled: vertical or horizontal. | PdfScrollDirection | PdfScrollDirection.vertical |
canShowScrollHead | Shows or hides the scroll head indicator. | bool | true |
canShowPaginationDialog | Shows or hides the page navigation dialog. | bool | true |
enableTextSelection | Enables or disables text selection. | bool | true |
enableDoubleTapZooming | Enables or disables double-tap zoom. | bool | true |
canShowTextSelectionMenu | Shows or hides the built-in text selection context menu. | bool | true |
currentSearchTextHighlightColor | Color for the current search match highlight. | Color | Orange at 60% opacity |
otherSearchTextHighlightColor | Color for other search match highlights. | Color | Orange at 30% opacity |
password | Password for opening encrypted PDF documents. | String? | — |
onDocumentLoaded | Callback when document loads successfully. | PdfDocumentLoadedCallback? | — |
onDocumentLoadFailed | Callback when document fails to load. | PdfDocumentLoadFailedCallback? | — |
onPageChanged | Callback when the visible page changes. | PdfPageChangedCallback? | — |
onZoomLevelChanged | Callback when the zoom level changes. | PdfZoomLevelChangedCallback? | — |
onTextSelectionChanged | Callback when text selection changes. | PdfTextSelectionChangedCallback? | — |
---
Enumerations
PdfInteractionMode
| Value | Description |
|---|---|
PdfInteractionMode.selection | Enables text selection on touch/drag. |
PdfInteractionMode.pan | Enables pan/scroll without text selection. |
PdfPageLayoutMode
| Value | Description |
|---|---|
PdfPageLayoutMode.continuous | Pages are displayed in a continuous scrollable list (default). |
PdfPageLayoutMode.single | One page is displayed at a time. |
Scrolling in Flutter SfPdfViewer
The SfPdfViewer has built-in scrolling capability. Avoid placing it inside other scrollable widgets (e.g., ScrollView) to prevent unexpected behavior.
---
Scroll to a Specific Offset Programmatically
final PdfViewerController _pdfViewerController = PdfViewerController();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Flutter PDF Viewer'),
actions: <Widget>[
IconButton(
icon: const Icon(Icons.arrow_drop_down_circle, color: Colors.white),
onPressed: () {
_pdfViewerController.jumpTo(yOffset: 1500);
},
),
],
),
body: SfPdfViewer.network(
'https://cdn.syncfusion.com/content/PDFViewer/flutter-succinctly.pdf',
controller: _pdfViewerController,
),
);
}---
Get Current Scroll Offset
IconButton(
icon: const Icon(Icons.info_outline, color: Colors.white),
onPressed: () {
_pdfViewerController.jumpToPage(3);
print('Horizontal offset: ${_pdfViewerController.scrollOffset.dx}');
print('Vertical offset: ${_pdfViewerController.scrollOffset.dy}');
},
)---
Scrolling Reference
PdfViewerController Properties and Methods
| API | Description | Type |
|---|---|---|
jumpTo({double xOffset, double yOffset}) | Moves the scroll position to the specified offset. Both parameters optional; defaults to (0, 0). | Method |
scrollOffset | Returns the current scroll position as an Offset object. | Offset property |
Offset Properties
| Property | Description | Type |
|---|---|---|
dx | The horizontal scroll offset. | double |
dy | The vertical scroll offset. | double |
Warning: Do not placeSfPdfViewerinsideScrollViewor similar scrollable widgets, as this causes unexpected scrolling behavior.
Custom Signature Pad with SfPdfViewer
Use SfSignaturePad from syncfusion_flutter_signaturepad to replace the built-in signature pad dialog in SfPdfViewer. Hide the built-in dialog using canShowSignaturePadDialog: false and show a custom dialog via onFormFieldFocusChange. ---
Check Dependency Setup
Add both packages to pubspec.yaml:
dependencies:
syncfusion_flutter_pdfviewer: ^33.2.8
syncfusion_flutter_signaturepad: ^33.2.8Run:
flutter pub getNotes:
- Use the latest stable version of the package from pub.dev.
---
Imports
import 'dart:typed_data';
import 'dart:ui' as ui;
import 'package:flutter/material.dart';
import 'package:syncfusion_flutter_pdfviewer/pdfviewer.dart';
import 'package:syncfusion_flutter_signaturepad/signaturepad.dart';---
Hide Built-in Signature Pad Dialog
SfPdfViewer.asset(
'assets/form_document.pdf',
canShowSignaturePadDialog: false,
)---
Create Custom Signature Pad – Full Sample
final GlobalKey<SfPdfViewerState> _pdfViewerKey = GlobalKey();
final GlobalKey<SfSignaturePadState> _signaturePadKey = GlobalKey();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Flutter PDF Viewer'),
),
body: SfPdfViewer.asset(
'assets/form_document.pdf',
key: _pdfViewerKey,
canShowSignaturePadDialog: false,
onFormFieldFocusChange: (PdfFormFieldFocusChangeDetails details) {
if (details.formField is PdfSignatureFormField && details.hasFocus) {
final PdfSignatureFormField signatureFormField =
details.formField as PdfSignatureFormField;
_showCustomSignaturePadDialog(signatureFormField);
}
},
),
);
}
/// Displays the custom signature pad dialog.
Future<void> _showCustomSignaturePadDialog(
PdfSignatureFormField formField) async {
await showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: const Text(
'Draw your Signature',
textAlign: TextAlign.center,
),
titlePadding: const EdgeInsets.all(8),
contentPadding: const EdgeInsets.all(12),
content: Container(
height: 200,
width: 300,
decoration: BoxDecoration(
border: Border.all(color: Colors.grey),
),
child: SfSignaturePad(
key: _signaturePadKey,
),
),
actions: [
TextButton(
onPressed: () {
// Clears the strokes in the signature pad.
_signaturePadKey.currentState!.clear();
},
child: const Text('Clear'),
),
TextButton(
onPressed: () async {
Navigator.pop(context);
await _saveSignature(formField);
},
child: const Text('Save'),
),
],
);
},
);
}
/// Converts the signature pad drawing to an image and assigns it to the form field.
Future<void> _saveSignature(PdfSignatureFormField formField) async {
final ui.Image image =
await _signaturePadKey.currentState!.toImage(pixelRatio: 3.0);
final ByteData? imageBytes =
await image.toByteData(format: ui.ImageByteFormat.png);
if (imageBytes != null) {
final Uint8List data = imageBytes.buffer.asUint8List();
formField.signature = data;
}
}---
Key APIs Reference
SfPdfViewer Properties
| Property | Description | Type | Default |
|---|---|---|---|
canShowSignaturePadDialog | Shows or hides the built-in signature pad dialog when a signature field is tapped. | bool | true |
onFormFieldFocusChange | Callback triggered when focus enters or leaves a text box or signature field. Use to detect signature field tap. | PdfFormFieldFocusChangeCallback? | — |
PdfFormFieldFocusChangeDetails
| Property | Type | Description |
|---|---|---|
formField | PdfFormField | The form field instance that gained or lost focus. |
hasFocus | bool | true when the field gains focus (tapped); false when it loses focus. |
SfSignaturePad (from syncfusion_flutter_signaturepad)
| Member | Type | Description |
|---|---|---|
key | GlobalKey<SfSignaturePadState> | Key used to access state methods. |
clear() | Method | Clears all drawn strokes from the signature pad. |
toImage({double pixelRatio}) | Future<ui.Image> | Converts the drawn signature to a ui.Image. |
PdfSignatureFormField
| Property | Type | Description |
|---|---|---|
signature | Uint8List? | Assigns PNG image bytes as the signature. Set to null to remove. |
---
Notes
onFormFieldFocusChangeonly fires for text box and signature form fields.- Call
toImage(pixelRatio: 3.0)for a high-resolution signature image. - Use
image.toByteData(format: ui.ImageByteFormat.png)to convert to PNG bytes before assigning toformField.signature.
Text Search in Flutter SfPdfViewer
The SfPdfViewer allows you to search for text in a PDF document and navigate through all occurrences. Search is performed asynchronously on mobile/desktop (results return page by page via addListener) and synchronously on web.
Note: Import'package:syncfusion_flutter_pdf/pdf.dart'if you useTextSearchOption.
---
Initiate Text Search and Retrieve Results
late PdfViewerController _pdfViewerController;
late PdfTextSearchResult _searchResult;
@override
void initState() {
_pdfViewerController = PdfViewerController();
_searchResult = PdfTextSearchResult();
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Flutter PDF Viewer'),
actions: <Widget>[
IconButton(
icon: const Icon(Icons.search, color: Colors.white),
onPressed: () {
_searchResult = _pdfViewerController.searchText(
'the',
searchOption: TextSearchOption.caseSensitive,
);
if (kIsWeb) {
print('Total instances: ${_searchResult.totalInstanceCount}');
} else {
_searchResult.addListener(() {
if (_searchResult.hasResult && _searchResult.isSearchCompleted) {
print('Total instances: ${_searchResult.totalInstanceCount}');
}
});
}
},
),
],
),
body: SfPdfViewer.network(
'https://cdn.syncfusion.com/content/PDFViewer/flutter-succinctly.pdf',
controller: _pdfViewerController,
),
);
}---
Navigate to Next and Previous Search Instance
// Navigate to the next match
_searchResult.nextInstance();
// Navigate to the previous match
_searchResult.previousInstance();---
Cancel / Clear Text Search
setState(() {
_searchResult.clear();
});---
Customize Search Highlight Colors
body: SfPdfViewer.network(
'https://cdn.syncfusion.com/content/PDFViewer/flutter-succinctly.pdf',
controller: _pdfViewerController,
currentSearchTextHighlightColor: Colors.blue,
otherSearchTextHighlightColor: Colors.yellow,
),---
Detect No Results Found
_searchResult.addListener(() {
if (_searchResult.isSearchCompleted && _searchResult.totalInstanceCount == 0) {
print('No matches found.');
}
});---
Text Search Properties and Methods Reference
PdfViewerController Methods
| Method | Description |
|---|---|
searchText(String text, {TextSearchOption? searchOption}) | Searches for text and returns a PdfTextSearchResult. |
PdfTextSearchResult Properties and Methods
| API | Description | Type |
|---|---|---|
totalInstanceCount | Total number of matched instances in the document. | int |
currentInstanceIndex | Index of the currently highlighted instance. | int |
hasResult | Whether any match was found. | bool |
isSearchCompleted | Whether the search has finished across all pages. | bool |
nextInstance() | Navigates to the next matched instance. | Method |
previousInstance() | Navigates to the previous matched instance. | Method |
clear() | Cancels the search and clears all highlights. | Method |
addListener(VoidCallback) | Registers a listener for search result updates (mobile/desktop only). | Method |
SfPdfViewer Search Properties
| Property | Description | Type | Default |
|---|---|---|---|
currentSearchTextHighlightColor | Highlight color for the current matched instance. | Color | Color(0xFFE56E00) at 60% opacity |
otherSearchTextHighlightColor | Highlight color for all other matched instances. | Color | Color(0xFFE56E00) at 30% opacity |
TextSearchOption Enum
| Value | Description |
|---|---|
TextSearchOption.none | Case-insensitive search (default). |
TextSearchOption.caseSensitive | Case-sensitive search. |
TextSearchOption.wholeWords | Match whole words only. |
TextSearchOption.both | Case-sensitive and whole words. |
Text Selection in Flutter SfPdfViewer
On touch devices, text can be selected by long-pressing on a word, which shows selection handles. On desktop web browsers, text can be selected by dragging the mouse in selection interaction mode. Note that images are not selectable and multi-page selection is not supported.
---
Enable or Disable Text Selection
@override
Widget build(BuildContext context) {
return Scaffold(
body: SfPdfViewer.network(
'https://cdn.syncfusion.com/content/PDFViewer/flutter-succinctly.pdf',
enableTextSelection: false,
),
);
}Note: On desktop web browsers,enableTextSelectionhas no effect inpaninteraction mode.
---
Customise Text Selection and Handle Colors
void main() => runApp(MaterialApp(
title: 'PDF Viewer Demo',
theme: ThemeData(
textSelectionTheme: const TextSelectionThemeData(
selectionColor: Colors.red,
selectionHandleColor: Colors.blue,
),
),
home: const PdfViewerPage(),
));---
Hide the Built-in Text Selection Context Menu
@override
Widget build(BuildContext context) {
return Scaffold(
body: SfPdfViewer.network(
'https://cdn.syncfusion.com/content/PDFViewer/flutter-succinctly.pdf',
canShowTextSelectionMenu: false,
),
);
}---
Add Text Selection Changed Callback
@override
Widget build(BuildContext context) {
return Scaffold(
body: SfPdfViewer.network(
'https://cdn.syncfusion.com/content/PDFViewer/flutter-succinctly.pdf',
onTextSelectionChanged: (PdfTextSelectionChangedDetails details) {
if (details.selectedText != null) {
print('Selected: ${details.selectedText}');
}
},
),
);
}---
Get Selected Text Lines
final GlobalKey<SfPdfViewerState> _pdfViewerKey = GlobalKey();
late PdfViewerController _pdfViewerController;
@override
void initState() {
_pdfViewerController = PdfViewerController();
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Flutter PDF Viewer'),
actions: <Widget>[
IconButton(
icon: const Icon(Icons.highlight),
onPressed: () {
final List<PdfTextLine>? selectedLines =
_pdfViewerKey.currentState?.getSelectedTextLines();
if (selectedLines != null && selectedLines.isNotEmpty) {
_pdfViewerController.addAnnotation(
HighlightAnnotation(textBoundsCollection: selectedLines),
);
}
},
),
],
),
body: SfPdfViewer.asset(
'assets/sample.pdf',
key: _pdfViewerKey,
controller: _pdfViewerController,
),
);
}---
Get PDF Text Line Details
@override
Widget build(BuildContext context) {
return Scaffold(
body: SfPdfViewer.network(
'https://cdn.syncfusion.com/content/PDFViewer/flutter-succinctly.pdf',
onTextSelectionChanged: (PdfTextSelectionChangedDetails details) {
final List<PdfTextLine>? lines = details.selectedTextLines;
if (lines != null) {
for (final PdfTextLine line in lines) {
print('Text : ${line.text}');
print('Page : ${line.pageNumber}');
print('Bounds : ${line.bounds}');
}
}
},
),
);
}---
Clear Text Selection
_pdfViewerController.clearSelection();---
Text Selection Properties Reference
| API | Description | Type | Default |
|---|---|---|---|
enableTextSelection | Enables or disables text selection. | Widget property | true |
canShowTextSelectionMenu | Shows or hides the built-in text selection context menu. | Widget property | true |
onTextSelectionChanged | Callback triggered on text selection changes. Returns PdfTextSelectionChangedDetails. | Widget callback | — |
clearSelection() | Clears the current text selection. | PdfViewerController method | — |
getSelectedTextLines() | Returns the list of selected PdfTextLine objects. | SfPdfViewerState method | — |
PdfTextSelectionChangedDetails Properties
| Property | Description | Type |
|---|---|---|
selectedText | The currently selected text string. null if nothing is selected. | String? |
globalSelectedRegion | The global bounding rectangle of the selected text region. | Rect? |