Blog Post

How to build a Flutter PDF viewer

Jonathan D. Rhyne
Illustration: How to build a Flutter PDF viewer
Information

This article was first published in March 2022 and was updated in September 2024.

Flutter is an open source framework developed by Google that allows for creating natively compiled applications for mobile, web, and desktop from a single codebase in Dart. This post will walk through the process of setting up a basic PDF viewer in Flutter to handle single-page documents.

It’ll start by exploring how to choose the right package for PDF viewing from a range of open source options. Then, you’ll proceed to integrate the selected package into a Flutter project, resulting in a functional PDF viewer app.

Choosing the right PDF package for Flutter

When selecting a PDF library for Flutter, it’s essential to evaluate your requirements and consider factors like package quality and functionality. For simple use cases, exploring open source libraries is a great starting point. For more advanced needs, Nutrient offers a robust Flutter PDF SDK with comprehensive features.

To find suitable packages, searching for pdf on pub.dev reveals a plethora of options. Key factors to consider include:

  • Pub points — Reflects the quality of the package based on static analysis, including support for null safety and adherence to Dart conventions.

  • Popularity — Indicates the number of developers using the package.

  • Update frequency — A recent update date often signifies an actively maintained project.

  • Verified publisher — Some packages come from verified publishers, adding an extra layer of trust.

Among the search results, the following packages are noteworthy:

  • flutter_pdfview — A Flutter plugin that provides a PDFView widget on Android and iOS.

  • native_pdf_view — A Flutter plugin for rendering PDF files on web, macOS, Windows, Android, and iOS.

  • advance_pdf_viewer — A Flutter plugin for handling PDF files.

After a quick assessment of the three packages, flutter_pdfview proved to be the most suitable for the goal of the experiment of implementing a simple PDF viewer. It has an example included in the GitHub repository, the configuration steps are easy to follow, and under its hood, it’s based on a Google library called PDFium — and here at Nutrient, we love PDFium! ❤️

Building a PDF viewer with flutter_pdfview

flutter_pdfview is a Flutter package that allows you to render PDFs on both Android and iOS platforms. It provides a seamless way to display PDF files within your Flutter app, offering features such as page navigation, zooming, and more. It exposes some configuration options to provide a customized experience, and there’s an example app included in the GitHub repository.

To keep the use case simple, this post will use flutter_pdfview to show a single-page PDF document on an Android device with API 30.

The main layout of the app will be a widget showing the rendered PDF document, and it’ll allow simple gestures like pinch-to-zoom and dragging the zoomed page.

Getting started

To get started, ensure you have Flutter installed and set up on your development machine. You can check this by running the following command:

flutter doctor

This command will verify if you have everything in place to start developing with Flutter.

Step 1 — Creating a new Flutter project

Begin by creating a new Flutter project. Open your terminal and run:

flutter create pdf_viewer_app

Navigate to your project directory:

cd pdf_viewer_app

Step 2 — Adding the flutter_pdfview dependency

Next, add the flutter_pdfview package to your pubspec.yaml file under dependencies:

...
dependencies:
  flutter:
    sdk: flutter
+ flutter_pdfview: ^1.2.7
...
Information

Be careful with the above, as spaces matter in YAML files.

Run flutter pub get to install the package.

Step 3 — Updating the Android and iOS configurations

For Android, ensure your minSdkVersion is at least 21 in android/app/build.gradle:

defaultConfig {
    ...
    minSdkVersion 21
    ...
}

For iOS, enable Swift support by adding the following to your ios/Podfile:

platform :ios, '11.0'

Step 4 — Creating the PDF viewer widget

Now you’ll create the PDF viewer widget. Open lib/main.dart and replace its content with the following code:

import 'package:flutter/material.dart';
import 'package:flutter_pdfview/flutter_pdfview.dart';
import 'package:path_provider/path_provider.dart';
import 'dart:io';
import 'dart:async';
import 'package:flutter/services.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: PDFScreen(),
    );
  }
}

class PDFScreen extends StatefulWidget {
  @override
  _PDFScreenState createState() => _PDFScreenState();
}

class _PDFScreenState extends State<PDFScreen> {
  String? _localPath;
  int? _totalPages = 0;
  int? _currentPage = 0;
  bool pdfReady = false;
  late PDFViewController _pdfViewController;

  @override
  void initState() {
    super.initState();
    fromAsset('assets/sample.pdf', 'sample.pdf').then((file) {
      setState(() {
        _localPath = file.path;
        pdfReady = true;
      });
    });
  }

  Future<File> fromAsset(String asset, String fileName) async {
    final byteData = await rootBundle.load(asset);
    final file = File('${(await getTemporaryDirectory()).path}/$fileName');
    await file.writeAsBytes(byteData.buffer.asUint8List(byteData.offsetInBytes, byteData.lengthInBytes));
    return file;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('PDF Viewer'),
        actions: _totalPages != null
            ? <Widget>[
                Center(child: Text('${_currentPage! + 1} / $_totalPages')),
                IconButton(
                  icon: Icon(Icons.chevron_left),
                  onPressed: () {
                    setState(() {
                      _currentPage = (_currentPage! - 1).clamp(0, _totalPages! - 1);
                    });
                    _pdfViewController.setPage(_currentPage!);
                  },
                ),
                IconButton(
                  icon: Icon(Icons.chevron_right),
                  onPressed: () {
                    setState(() {
                      _currentPage = (_currentPage! + 1).clamp(0, _totalPages! - 1);
                    });
                    _pdfViewController.setPage(_currentPage!);
                  },
                ),
              ]
            : null,
      ),
      body: pdfReady
          ? PDFView(
              filePath: _localPath,
              enableSwipe: true,
              swipeHorizontal: true,
              autoSpacing: false,
              pageFling: false,
              onRender: (_pages) {
                setState(() {
                  _totalPages = _pages;
                });
              },
              onViewCreated: (PDFViewController vc) {
                _pdfViewController = vc;
              },
              onPageChanged: (page, total) {
                setState(() {
                  _currentPage = page;
                });
              },
              onError: (error) {
                print(error.toString());
              },
              onPageError: (page, error) {
                print('$page: ${error.toString()}');
              },
            )
          : Center(child: CircularProgressIndicator()),
    );
  }
}

Step 5 — Adding a sample PDF

Add a sample PDF document named sample.pdf to your assets folder. If the folder doesn’t exist, create it in the root directory of your project. Then, update your pubspec.yaml file to include the assets:

flutter:
+  assets:
+    - assets/sample.pdf

Step 6 — Running the app

To run the PDF viewer, make sure to connect a physical Android device or open an emulator from the Android Virtual Device Manager. Then from the command line, type:

flutter run

After a short building process, the PDF viewer app will be ready to use on the Android device. 🎉

Conclusion

In this blog post, we covered some factors to look at when selecting a PDF package from a set of open source packages, and we showed you how to build a PDF viewer using the open source Flutter PDF library, flutter_pdfview, which is good for solving simple use cases without too much hassle. However, AndroidPdfViewer — the library flutter_pdfview is based on — hasn’t received an update in a few years, and it’s still published to JCenter, an artifact repository that’s now read-only.

For more complex customizations, Nutrient offers its own Flutter PDF library with a detailed getting started guide. Nutrient ships with many features out of the box, including:

  • A customizable UI that’s simple and easy to use.

  • Embeddable prebuilt tools to easily add functionality like annotating documents, adding digital signatures to a PDF form, and much more.

  • Multiple file type support — from image files (JPG, PNG, TIFF) to PDF documents.

It also features active development cycles with constant improvements and bug fixes. To get started with Nutrient Flutter SDK, check out our free trial. If you have any questions about our Flutter PDF library, please don’t hesitate to reach out to us. We’re happy to help!

FAQ

Here are a few frequently asked questions about building a Flutter PDF viewer.

How do I choose the right PDF package for Flutter?

When selecting a PDF package, consider factors like pub points, popularity, update frequency, and whether the package supports your required features. Popular packages for Flutter include flutter_pdfview, native_pdf_view, and advance_pdf_viewer.

How do I integrate flutter_pdfview into my Flutter project?

To integrate flutter_pdfview, add it to your pubspec.yaml dependencies, include path_provider for file management, and ensure you have the jcenter() repository in your Android build script. Follow the setup instructions and add your PDF document to the project’s assets.

What are the main features of flutter_pdfview?

flutter_pdfview provides a widget for rendering PDFs in Flutter applications. It supports basic functionalities like viewing PDF documents with pinch-to-zoom and page navigation. It uses the AndroidPdfViewer library under the hood for rendering.

Can I customize the PDF viewer with flutter_pdfview?

flutter_pdfview offers some configuration options to customize the viewing experience, such as setting up page zoom and scrolling. For more extensive customization, consider using more advanced libraries or integrating with tools like Nutrient.

What should I do if I encounter issues with flutter_pdfview?

If you face issues with flutter_pdfview, check the GitHub repository for troubleshooting tips and open issues. For more complex needs, consider alternative solutions like Nutrient Flutter SDK, which offers additional support and features.

Author
Jonathan D. Rhyne Co-Founder and CEO

Jonathan joined PSPDFKit in 2014. As CEO, Jonathan defines the company’s vision and strategic goals, bolsters the team culture, and steers product direction. When he’s not working, he enjoys being a dad, photography, and soccer.

Explore related topics

Share post
Free trial Ready to get started?
Free trial