flutter_pdfview

repository·main·Indexed 43 days ago

https://github.com/endigo/flutter_pdfview

A Flutter plugin providing native PDF viewing capabilities for iOS and Android using PDFKit and AndroidPdfViewer. It includes the PDFView widget for rendering documents via filePath or pdfData, and a PDFViewController to programmatically manage page navigation, zoom levels, and screenshots. Version 1.4.5 supports FitPolicy for scaling, night mode, and custom gesture recognizers for use within scrollable widgets.

Tokens
3.5K
Snippets
11
Records
14
Agent score
54%

What's inside flutter_pdfview

  1. Handle gestures when using PDFView inside scrollable widgets

    main

    If you embed PDFView inside a scrollable parent (like ListView, SingleChildScrollView, or PageView), the parent may intercept drag gestures, preventing swiping within the PDF (especially on iOS). To fix this, pass an EagerGestureRecognizer to the gestureRecognizers property so the PDF view consumes gestures within its bounds.

    import 'package:flutter/foundation.dart';
    import 'package:flutter/gestures.dart';
    
    PDFView(
      filePath: path,
      gestureRecognizers: {
        Factory<OneSequenceGestureRecognizer>(() => EagerGestureRecognizer()),
      },
    )
  2. Customize iOS launch screen assets

    main

    To customize the launch screen for the iOS version of your Flutter application, you can replace the image files located in the Assets.xcassets/LaunchImage.imageset directory with your own assets.

    Alternatively, you can manage these assets using Xcode:

    1. Open the iOS project in Xcode by running open ios/Runner.xcworkspace from your terminal.
    2. In the Xcode Project Navigator, navigate to Runner/Assets.xcassets.
    3. Drag and drop your desired images into the asset catalog.
    open ios/Runner.xcworkspace
  3. Manage PDF view state with PDFViewController

    main

    The PDFViewController allows you to programmatically control a PDFView instance. An instance is provided to you via the onViewCreated callback of the PDFView widget once the platform view is ready.

    Lifecycle Note: The controller is automatically disposed of when the owning PDFView is removed from the widget tree or when a different document is loaded. You generally do not need to call dispose() manually.

    PDFView(onViewCreated: (PDFViewController controller) {
      // Use the controller to interact with the PDF
    });
  4. Manage gestures in PDFView when using scrollable parents

    main

    When PDFView is used inside a scrollable widget (such as a ListView or SingleChildScrollView), the parent widget may intercept pointer events (e.g., vertical drags).

    To ensure the PDFView can handle its own gestures (like zooming or swiping), you must pass a set of gestureRecognizers to the PDFView constructor. The PDFView will claim gestures that are recognized by any of the recognizers provided in this set.

  5. Example: Basic PDFView implementation

    main

    This example demonstrates a standard PDFView configuration including lifecycle callbacks and error handling.

    PDFView(
      filePath: path,
      enableSwipe: true,
      swipeHorizontal: true,
      autoSpacing: false,
      pageFling: false,
      showScrollIndicators: true,
      backgroundColor: Colors.grey,
      onRender: (_pages) {
        setState(() {
          pages = _pages;
          isReady = true;
        });
      },
      onError: (error) {
        print(error.toString());
      },
      onPageError: (page, error) {
        print('$page: ${error.toString()}');
      },
      onViewCreated: (PDFViewController pdfViewController) {
        _controller.complete(pdfViewController);
      },
      onPageChanged: (int page, int total) {
        print('page change: $page/$total');
      },
      onLoadComplete: (int? pages) {
        print('# of pages: $pages');
      },
      onDraw: (double xOffset, double yOffset, double scale) {
        print('onDraw');
      },
    ),
  6. Use PDFViewController methods

    main

    The onViewCreated callback provides a PDFViewController, which allows you to programmatically control the PDF view. Available methods include:

    • getPageCount(): Returns Future<int> (total page count).
    • getCurrentPage(): Returns Future<int> (current page).
    • setPage(int page): Returns Future<bool> (go to specific page).
    • getCurrentPageSize(): Returns Future<Size> (width and height of loaded page).
    • getScreenshot(String fileName): Returns Future<String> (creates a PNG and saves to fileName).
    • getPosition(): Returns Future<Offset> (top left position relative to origin).
    • getScale(): Returns Future<double> (current zoom value).
    • setPosition(Offset position): Returns Future<bool> (set top left position).
    • setScale(double scale): Returns Future<bool> (set zoom value).
    • setZoomLimits(double minZoom, double midZoom, double maxZoom): Sets zoom bounds.
    • reload(): Returns Future<bool> (reloads the document).
  7. Configure PDFView options

    main

    The PDFView widget accepts several configuration options for controlling behavior, appearance, and lifecycle callbacks. Note that some options are platform-specific (Android vs iOS).

    | Name | Android | iOS | Default |
    |:---|:---:|:---:|:---:|
    | `defaultPage` | ✅ | ✅ | `0` |
    | `onViewCreated` | ✅ | ✅ | `null` |
    | `onRender` | ✅ | ✅ | `null` |
    | `onPageChanged` | ✅ | ✅ | `null` |
    | `onLoadComplete` | ✅ | ✅ | `null` |
    | `onDraw` | ✅ | ✅ | `null` |
    | `onError` | ✅ | ✅ | `null` |
    | `onPageError` | ✅ | ❌ | `null` |
    | `onLinkHandle` | ✅ | ✅ | `null` |
    | `gestureRecognizers` | ✅ | ✅ | `null` |
    | `filePath` | ✅ | ✅ | |
    | `pdfData` | ✅ | ✅ | |
    | `fitPolicy` | ✅ | ✅ | `FitPolicy.WIDTH` |
    | `enableSwipe` | ✅ | ✅ | `true` |
    | `swipeHorizontal` | ✅ | ✅ | `false` |
    | `password` | ✅ | ✅ | `null` |
    | `nightMode` | ✅ | ❌ | `false` |
    | `autoSpacing*` | ✅ | ✅ | `true` |
    | `pageFling` | ✅ | ✅ | `true` |
    | `pageSnap` | ✅ | ❌ | `true` |
    | `preventLinkNavigation` | ✅ | ✅ | `false` |
    | `backgroundColor` | ✅ | ✅ | `null` |
    | `minZoom` | ✅ | ✅ | `1.0` |
    | `maxZoom` | ✅ | ✅ | `4.0` |
    | `showScrollIndicators*` | ✅ | ✅ | `false` |
    
    *Notes: `showScrollIndicators` is ignored on iOS when `pageFling: true` and `swipeHorizontal: true` are both active. `autoSpacing` only adds gaps between pages and does not affect initial zoom or `fitPolicy`.
  8. Handle PDFView events and callbacks

    main

    PDFView provides several callbacks to interact with the document lifecycle and user interactions:

    CallbackDescription
    onViewCreatedInvoked once the PDFViewController is created.
    onRenderReturns the PDF page count.
    onPageChangedReturns the current page index and the total page count.
    onErrorInvoked when an error is handled in native code.
    onPageErrorInvoked when a specific page fails to render.
    onLinkHandlerUsed when preventLinkNavigation is true; allows customizing link navigation.
    onLoadCompleteInvoked once the document has finished loading, providing the page count.
    onDrawInvoked while the document is being drawn, providing current offsets and scale.
  9. Control zoom and scale with PDFViewController

    main

    You can manage the zoom level and scale of the PDF document using the following methods:

    • Set zoom scale: Use setScale(double scale) to set a specific zoom level. Returns true if the scale was accepted.
    • Set zoom limits: Use setZoomLimits(double minZoom, double midZoom, double maxZoom) to define the minimum, middle, and maximum zoom levels allowed. Returns true if the limits were applied.
    • Get current scale: Use getScale() to retrieve the current zoom scale. This waits for any pending setScale calls to complete.
    • Get current page size: Use getCurrentPageSize() to get the size (in points) of the currently displayed page as a Size object.
    // Set a specific zoom level
    await controller.setScale(2.0);
    
    // Set zoom constraints
    await controller.setZoomLimits(0.5, 1.0, 3.0);
    
    // Get current scale
    double currentScale = await controller.getScale();
  10. Use the PDFView widget to display PDF documents

    main

    The PDFView widget renders a PDF document using the platform's native viewer. You must provide exactly one source: either a filePath (a string pointing to a file on disk) or pdfData (a Uint8List containing the raw bytes).

    Key Behaviors:

    • Document Changes: Changing filePath or pdfData recreates the underlying platform view to load the new document.
    • Setting Changes: Changing other configuration options (like nightMode or maxZoom) forwards the changes to the native view via a method channel without recreating the view.
    • Gesture Handling: If the PDFView is placed inside a scrollable widget (like a ListView), you may need to provide gestureRecognizers to ensure the PDF view correctly claims pointer events.

    Common Configuration Options:

    • enableSwipe: Enables/disables swiping to change pages (default: true).
    • swipeHorizontal: Enables horizontal swiping (default: false).
    • fitPolicy: Controls how pages scale to the viewport. Options include FitPolicy.WIDTH, FitPolicy.HEIGHT, and FitPolicy.BOTH.
    • nightMode: Enables night mode (default: false).
    • maxZoom / minZoom: Sets the zoom boundaries (default maxZoom is 4.0, minZoom is 1.0).
    PDFView( 
      filePath: '/path/to/document.pdf', 
      onViewCreated: (PDFViewController controller) {
        // Handle view creation
      },
      onPageChanged: (int? page, int? total) {
        // Handle page changes
      },
    ) 
  11. Navigate and scroll using PDFViewController

    main

    Use the PDFViewController to jump to specific pages or scroll to specific offsets within the document.

    • Jump to a page: Use setPage(int page) to jump to a zero-based page index. Returns true if the jump succeeded.
    • Scroll to position: Use setPosition(Offset position) to scroll to a specific x and y offset. Returns true if the native view accepted the new offset. This method is serialized to ensure calls are processed in order.
    • Get current page: Use getCurrentPage() to retrieve the zero-based index of the currently displayed page.
    • Get page count: Use getPageCount() to get the total number of pages in the document.
    // Jump to the first page
    await controller.setPage(0);
    
    // Scroll to a specific offset
    await controller.setPosition(Offset(0, 100));
    
    // Get current page info
    int? currentPage = await controller.getCurrentPage();
    int? totalPages = await controller.getPageCount();