pdfrx 0.4.25 copy "pdfrx: ^0.4.25" to clipboard
pdfrx: ^0.4.25 copied to clipboard

High speed zooming/scrolling PDF viewer implementation that supports mobile, desktop, and Web.

pdfrx #

pdfrx is a PDF viewer implementation built on the top of pdfium. The plugin currently supports Android, iOS, Windows, macOS, Linux, and Web.

Please note that "Web" is not shown in pub.dev's platform list, but IT DOES SUPPORT Web.

The plugin provides three different layers of APIs:

  • Easy to use Flutter widgets
  • Easy to use PDF APIs
  • pdfium bindings
    • Not encouraged but you can import package:pdfrx/src/pdfium/pdfium_bindings.dart

Getting Started #

The following fragment illustrates the easiest way to show a PDF file in assets:

class _MyAppState extends State<MyApp> {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Pdfrx example'),
        ),
        body: PdfViewer.asset('assets/hello.pdf'),
      ),
    );
  }
}

Installation #

Add this to your package's pubspec.yaml file and execute flutter pub get:

dependencies:
  pdfrx: ^0.4.25

Windows #

  • Ensure your Windows installation enables Developer Mode

    The build process internally uses symblic link and it requires Developer Mode to be enabled. Without this, you may encounter errors like this.

Web #

pdf.js is now automatically loaded and no modification to index.html is required.

macOS #

For macOS, Flutter app restrict its capability by enabling App Sandbox by default. You can change the behavior by editing your app's entitlements files depending on your configuration. See the discussion below.

Deal with App Sandbox #

The easiest option to access files on your disk, set com.apple.security.app-sandbox to false on your entitlements file though it is not recommended for releasing apps because it completely disables App Sandbox.

Another option is to use com.apple.security.files.user-selected.read-only along with file_selector_macos. The option is better in security than the previous option.

Anyway, the example code for the plugin illustrates how to download and preview internet hosted PDF file. It uses com.apple.security.network.client along with flutter_cache_manager:

<dict>
  <key>com.apple.security.app-sandbox</key>
  <true/>
  <key>com.apple.security.network.client</key>
  <true/>
</dict>

Open PDF File #

PdfViewer supports following functions to open PDF file on specific medium:

Deal with Password Protected PDF Files #

To support password protected PDF files, use passwordProvider to supply passwords interactively:

PdfViewer.asset(
  'assets/test.pdf',
  // Set password provider to show password dialog
  passwordProvider: _passwordDialog,

  ...
),

And, _passwordDialog function is defined like this:

Future<String?> _passwordDialog() async {
  final textController = TextEditingController();
  return await showDialog<String?>(
    context: context,
    barrierDismissible: false,
    builder: (context) {
      return AlertDialog(
        title: const Text('Enter password'),
        content: TextField(
          controller: textController,
          autofocus: true,
          keyboardType: TextInputType.visiblePassword,
          obscureText: true,
          onSubmitted: (value) => Navigator.of(context).pop(value),
        ),
        actions: [
          TextButton(
            onPressed: () => Navigator.of(context).pop(null),
            child: const Text('Cancel'),
          ),
          TextButton(
            onPressed: () => Navigator.of(context).pop(textController.text),
            child: const Text('OK'),
          ),
        ],
      );
    },
  );
}

When PdfViewer tries to open a password protected document, it calls the function passed to passwordProvider (except the first attempt; see below) repeatedly to get a new password until the document is successfully opened. And if the function returns null, the viewer will give up the password trials and the function is no longer called.

firstAttemptByEmptyPassword #

By default, the first password attempt uses empty password. This is because cnrypted PDF files frequently uses empty password for viewing purpose. It's normally useful but if you want to use authoring password, it can be disabled by setting firstAttemptByEmptyPassword to false.

Customizations #

You can customize the behaviour and visual by configuring PdfViewerParams.

Horizontal Scroll View #

By default, the pages are layed out vertically. You can customize the layout logic by PdfViewerParams.layoutPages:

layoutPages: (pages, params) {
  final height =
      pages.fold(0.0, (prev, page) => max(prev, page.height)) +
          params.margin * 2;
  final pageLayouts = <Rect>[];
  double x = params.margin;
  for (var page in pages) {
    pageLayouts.add(
      Rect.fromLTWH(
        x,
        (height - page.height) / 2, // center vertically
        page.width,
        page.height,
      ),
    );
    x += page.width + params.margin;
  }
  return PdfPageLayout(
    pageLayouts: pageLayouts,
    documentSize: Size(x, height),
  );
},

Showing Scroll Thumbs #

By default, the viewer does never show any scroll bars nor scroll thumbs. You can add scroll thumbs by using PdfViewerParams.viewerOverlayBuilder:

viewerOverlayBuilder: (context, size) => [
  // Add vertical scroll thumb on viewer's right side
  PdfViewerScrollThumb(
    controller: controller,
    orientation: ScrollbarOrientation.right,
    thumbSize: const Size(40, 25),
    thumbBuilder:
        (context, thumbSize, pageNumber, controller) =>
            Container(
      color: Colors.black,
      // Show page number on the thumb
      child: Center(
        child: Text(
          pageNumber.toString(),
          style: const TextStyle(color: Colors.white),
        ),
      ),
    ),
  ),
  // Add horizontal scroll thumb on viewer's bottom
  PdfViewerScrollThumb(
    controller: controller,
    orientation: ScrollbarOrientation.bottom,
    thumbSize: const Size(80, 30),
    thumbBuilder:
        (context, thumbSize, pageNumber, controller) =>
            Container(
      color: Colors.red,
    ),
  ),
],

Adding Page Number on Page Bottom #

If you want to add page number on each page, you can do that by PdfViewerParams.pageOverlayBuilder:

pageOverlayBuilder: (context, pageRect, page) {
  return Align(
    alignment: Alignment.bottomCenter,
    child: Text(page.pageNumber.toString(),
    style: const TextStyle(color: Colors.red)));
},

Loading Indicator #

PdfViewer.uri may take long time to download PDF file and you want to show some loading indicator. You can do that by PdfViewerParams.loadingBannerBuilder:

loadingBannerBuilder: (context, bytesDownloaded, totalBytes) {
  return Center(
    child: CircularProgressIndicator(
      // totalBytes may not be available on certain case
      value: totalBytes != null ? bytesDownloaded / totalBytes : null,
      backgroundColor: Colors.grey,
    ),
  );
}
89
likes
0
pub points
96%
popularity

Publisher

verified publisherespresso3389.jp

High speed zooming/scrolling PDF viewer implementation that supports mobile, desktop, and Web.

Repository (GitHub)
View/report issues

License

unknown (LICENSE)

Dependencies

collection, crypto, ffi, flutter, http, js, path, path_provider, rxdart, synchronized, url_launcher, vector_math

More

Packages that depend on pdfrx