pdfx_lite 3.9.0 copy "pdfx_lite: ^3.9.0" to clipboard
pdfx_lite: ^3.9.0 copied to clipboard

Minimal, legacy-free PDF rendering & viewing for Flutter (Android + iOS) — no CocoaPods, SPM-only, no web/desktop renderers. Replacement for pdfx.

3.9.0 #

  • Requires Dart 3.13 / Flutter 3.47 (sdk: ^3.13.0, flutter: >=3.47.0). Dart 3.13 rejects final/var in a parameter list, so packages generating or hand-writing that form no longer compile — this package never did, the bump only fixes the floor to the toolchain it is now built and tested against.
  • PdfLoadingFailure uses a primary constructor. No API change: same positional error / stackTrace fields.
  • Removed android/gradle/wrapper/ — the plugin has no gradlew and is built by the consuming app's wrapper, so the file was never read. The example app keeps its own wrapper (now Gradle 9.7.0).
  • parseCompressFormat uses Kotlin when guards (2 if quality == 100 ->) instead of a nested if/else inside a branch. Same mapping; guards need Kotlin 2.2, which AGP 9 already provides.

3.8.0 #

A review pass over lib/, android/ and ios/ — all bug fixes. New API: PdfControllerPinch.dispose() and PdfLoadingFailure. PdfPage.width/.height change value on iOS for rotated pages — they are the displayed size now, as they already were on Android.

Rotation · upstream #554 #

  • iOS getPage reported the raw mediaBox instead of the displayed size, so a rotated page was laid out with one aspect ratio and drawn with another — the texture path already worked in rotated space.
  • Document.render builds its transform explicitly rather than via getDrawingTransform, which preserves aspect ratio and will not scale up; the workaround for that double-scaled the page whenever it did not fit. Pages now stretch to fill exactly (as on Android), the background covers the whole bitmap rather than just the mapped mediaBox, and crop rects address the same region on both platforms.
  • A document whose pages differ in size kept the first page's placeholder layout: the relayout ran but scheduled no repaint.

Platform channel · Android #

  • updateTexture replied twice on a zero-size rect — the guard had no return.
  • Pigeon generates no error handling around an @async host method, so any throw before updateTexture's inner try left the reply unsent and the Dart future pending forever. updateTexture and resizeTexture are now total.
  • renderPage caught Exception, which excludes the OutOfMemoryError a large render fails with, and replied off the platform thread on four early returns.
  • surface.use { } released the SurfaceProducer's surface after every update, forcing the engine to reallocate an ImageReader and its buffers per frame while scrolling.
  • The dirty Rect was built as (left, top, width, height); it is (left, top, right, bottom), so any non-zero destination clipped.

Locking #

  • Dart's Lock was process-global, so unrelated documents serialized against each other. It is per-PdfDocument now, and PdfPageTexture.updateRect takes it.
  • iOS had no document lock at all: Repository's guarded the dictionary, not the CGPDFDocument it handed out, so the render queue raced the platform thread on a shared page cache. Document.withPage serializes every access.
  • Android's repository was a plain HashMap across those same two threads; it is a ConcurrentHashMap.

Platform divergences #

before now
generic error code "pdf_renderer" (Android) vs "RENDER_ERROR" (iOS) "RENDER_ERROR" on both
allowAntiAliasing honoured on iOS, ignored on Android honoured on both
resizeTexture, unknown id success on Android, failure on iOS failure on both
closeDocument, stale id throws on Android, no-op on iOS no-op on both
optional textureWidth/destinationX/sourceX/… force-unwrapped on Android, defaulted on iOS defaulted on both
format/backgroundColor/quality absent defaulted on Android, whole call failed on iOS defaulted on both
malformed backgroundColor throws on Android, falls back on iOS falls back on both

Leaks and lifecycle #

  • Reloading a document unregistered none of the outgoing textures.
  • Reusing one controller across two PdfViewPinches left the second permanently blank.
  • The controller's page-change listener was a closure, so it could never be removed; it accumulated per attach and fired against the detached state.
  • _PdfPageState.dispose() was never called by anything.
  • Post-dispose async work — setState, texture creation, a timer reaching View.of on a dead element — is guarded.
  • Two texture-creation races could orphan a texture.
  • Neither platform released anything on engine detach: Android dropped documents without closing their PdfRenderer and fd and left SurfaceProducers registered; iOS had no detach hook.
  • Android never deleted the cacheDir file it wrote per data/asset open.
  • Bitmaps are recycled on every path, including exceptions.

Performance #

  • The viewer rebuilt every frame at rest: build wrote isVisibleInsideView from a padding-inflated rect while _determinePagesToShow used an uninflated one, so pages in that band flipped between the two forever.
  • Page rects are recomputed only when the view size or a page size changes, not on every scroll and zoom frame.
  • Preview textures purge at 6 viewport-lengths rather than 33, and the real-size overlay at 2 rather than 8.
  • iOS pools pixel buffers instead of allocating a fresh multi-megabyte one per frame.

Correctness #

  • PdfPageImage.== compared only byte length while hashCode mixed in pageNumber, so equal objects could hash differently — which breaks Set and Map.
  • iOS force-unwrapped makeImage() and cropping(to:); an out-of-bounds cropRect was a guaranteed crash.
  • updateTex published the pixel buffer before unlocking it, treated a nil CGContext as success, and never checked the destination rect fit inside the buffer.
  • loadDocument(initialPage: n) reported page n but stayed on page 1.
  • A failed updateRect marked the page loaded, pinning it blank — nothing retries a loaded page.
  • getPageRect threw RangeError during a load instead of returning null.
  • A non-Exception load failure was flattened to Exception('Unknown error'); it is wrapped in PdfLoadingFailure.
  • unregisterTexture kept its retained UpdateTextureMessage, so a reused texture id could redraw the old page.

3.7.0 #

render() returns the bytes directly — no temp file, no dart:io #

Both platforms already encoded the page into an in-memory buffer and then wrote it to a temp file in pdf_renderer_cache/ purely so the reply could carry a path, which the Dart side immediately read back into a Uint8List and (usually) deleted. The bytes now travel over the pigeon bridge directly: RenderPageReply.path (String) became RenderPageReply.bytes (Uint8List). iOS drops writeToTempFile; Android encodes to a ByteArrayOutputStream instead of a FileOutputStream — no cacheDir write, and no orphaned files left behind on the (previously reachable) path where deletion was skipped.

With the round-trip gone, the package no longer imports dart:io at all — the last two uses were the temp-file read and a Platform.isIOS guard (now defaultTargetPlatform). pdfx_lite compiles for web as a result (it still has no web renderer — every native call throws — but a web build of a consuming app no longer fails at compile time on the unavoidable dart:io import, so a conditional showPdfSheet/stub split in the app is no longer needed).

Breaking only for the @visibleForTesting removeTempFile parameter on PdfPage.render(), which is removed — there is no temp file to leave behind. render() otherwise returns the same PdfPageImage with the same .bytes; normal callers are unaffected.

Dependencies #

Pigeon bumped to 27.2.0; the regenerated Dart/Kotlin/Swift bridge is byte-identical apart from the version stamp.

3.6.0 #

Dropped two abstractions with one implementor each #

Both were upstream's, and both were load-bearing there — for platforms and viewers this fork no longer has.

renderer/interfaces/ + renderer/io/ was a platform-interface split: an abstract PdfxPlatform / PdfDocument / PdfPage, and a …Pigeon subclass of each. It let web and desktop bring their own renderers. With Android and iOS both served by the one pigeon bridge, it had a single implementor. The renderer is now one library across four flat files, and the classes are concrete.

viewer/base/ held what upstream shared between its two viewers. PdfView is gone, so BasePdfController — the mixin that let PdfPageNumber accept either controller — described a set of one. PdfPageNumber now takes a PdfControllerPinch directly; PdfLoadingState lives with that controller and DefaultBuilderOptions with the builders. PdfTexture, a five-line function that renamed Flutter's Texture, is gone with the web and Windows implementations that needed the indirection.

No behaviour changed. Breaking only for BasePdfController (removed) and for anyone extending PdfDocument, PdfPage, PdfPageImage or PdfPageTexture, whose constructors are now private — they are created by the plugin, never by a caller. PdfxPlatform was never exported. Every other public name is unchanged.

Tightened three types that were lying #

  • PdfPageTexture.updateRect no longer takes documentId. A texture is created from exactly one page, so createTexture() now captures it; the parameter only ever invited you to name a different document. The argument survived from when a texture was tied to a native page id on iOS.
  • PdfPage.render returns PdfPageImage, not PdfPageImage?. It has always either thrown or returned an image.
  • PdfPageImage.width / .height are int, not int? — nullable only because every pigeon field is.

get_pixels.dart is folded into PdfPageImage as a private helper. It was its own library because upstream used it as a conditional-import seam, swapping in a web implementation — the machinery this fork deleted. It also did not return pixels: they are the encoded PNG/JPEG bytes.

3.5.0 #

Fixed: iOS leaked a CGPDFPage for every page ever displayed #

The viewer asks for each page with autoCloseAndroid: true. Android honoured it — open the page, read its size, close it. iOS ignored the flag and registered the page in a repository, while Dart marked the page closed anyway, so closePage was never sent and closeDocument never purged it. Every page a PdfViewPinch laid out stayed alive, with its document, for the life of the process.

Pages are no longer handles #

The leak was a symptom: Dart was pretending two incompatible native models were one. Android's PdfRenderer allows only one open page per document — a second openPage throws IllegalStateException — so its texture path never held a page and addressed pages by document + number. iOS held CGPDFPage handles and addressed them by id.

Both sides now open a page, use it, and close it, within a single call. No page repository, on either platform. Document.withPage on Android serializes those opens, which the platform requires: without it, a large render() overlapping texture updates fails every update on an Android 14 device (measured; an API 37 emulator tolerates two open pages, which is why this hid).

Breaking — all of this described a native resource that no longer exists:

Removed
PdfPage.close(), PdfPageAlreadyClosedException a page owns nothing to close
PdfDocument.getPage(n, autoCloseAndroid:) the parameter existed to paper over the platform difference
PdfPage.id, PdfPageImage.id pages have no id; they are addressed by number

PdfPage is now just its number and size. The document is still closed with PdfDocument.close(), as before.

Also drops a dead page cache in PdfDocumentPigeon: it was allocated, read, and never written, so every getPage already re-opened the page natively.

Verified on both platforms with example/lib/page_probe.dart, which exercises getPage, render, the texture path, and a deliberate render/texture overlap: Android on an API 34 device and an API 37 emulator, iOS by hand.

3.4.1 #

Fixed: Package.swift did not declare FlutterFramework #

Flutter wants an SPM plugin to declare the dependency explicitly, and without it the build stops before compiling any Swift:

Plugin pdfx_lite has a Package.swift for ios but is missing a dependency on FlutterFramework.

This surfaced building the example/ app. No Swift source changed; only the package manifest.

Verified on iOS #

example/lib/password_probe.dart now passes on iOS, giving the same 21 × OK / 6 × PdfPasswordProtectedException / 0 × PdfPasswordUnsupportedException as Android — which is the point of the fallback semantics: password: behaves identically on both platforms. The 3.3.0 and 3.4.0 Swift is therefore compiled and exercised, not merely reviewed.

3.4.0 #

password: is back — and actually read #

Additive: PdfDocument.openFile / openAsset / openData take an optional password: again. Upstream accepts one too, but neither mobile platform ever read it — the silent no-op that got the parameter removed in 3.0.0.

  • iOS — every version (CGPDFDocument.unlockWithPassword).
  • Android 15+ (API 35)PdfRenderer + LoadParams.
  • Android below API 35 — impossible on the platform, so it throws PdfPasswordUnsupportedException rather than ignoring the password. Ignoring would leave the document on the password-less path, which rejects any encrypted PDF: the correct password would come back as "password-protected", indistinguishable from a wrong one, and a caller would re-prompt forever. PdfDocument.isPasswordSupported() reports this up front.

password: is a fallback, tried only once a plain open has been refused. Android's LoadParams validates it unconditionally, so a permissions-only PDF (restricted, but with an empty user password) opens with no password yet fails when given one — a remembered password would have broken the documents that needed none.

PdfPasswordProtectedException now also covers a wrong password. It is not distinguished from a missing one: Android reports both as a single SecurityException.

Testing #

example/lib/password_probe.dart (3 sources × 3 fixtures × 3 passwords), on API 24 and API 37. (It passes on iOS too — see 3.4.1.)

3.3.0 #

Breaking #

Breaking in a minor again, same reasoning as 3.2.0 — the fork has essentially one consumer.

  • Removed PdfNotSupportException; PdfPage.render(format: webp) on iOS now throws UnsupportedError. It had one throw site: WebP on iOS. Whether that is an Exception or an Error decides the type, and it is an Error — a caller can know the answer up front from Platform.isIOS, with no I/O and no data dependence, so passing webp there is a precondition violation to be branched on, not a runtime failure to be caught:

    format: Platform.isIOS ? PdfPageImageFormat.png : PdfPageImageFormat.webp,
    

    UnsupportedError is dart:core's type for exactly this ("an instance cannot implement one of the methods in its signature"). Not PlatformException: that models an error which crossed the method channel, and this check runs in Dart and never reaches Swift — an opaque PlatformException("Unsupported format: 2") from the native side is what you get without the guard, and is what it exists to prevent.

  • PdfPageImageFormat.webp is documented as Android-only again. The warning was lost when upstream migrated to an enhanced enum — the old static const line was commented out and took the doc comment with it, so the value advertised nothing in autocomplete. iOS has no first-party WebP encoder at all (UIImage does JPEG/PNG only, and ImageIO's CGImageDestination rejects org.webmproject.webp — it reads WebP since iOS 14 but cannot write it), so this is a platform gap, not something the plugin can close without linking libwebp.

Fixes not in upstream #

  • iOS rejected readable PDFs that carry permission restrictions. openFile / openAsset tested CGPDFDocument.isEncrypted, but openData tested isUnlocked — and those are not the same question. A PDF encrypted with an empty user password (permissions only: no printing, no copying — very common for invoices and statements) is unlocked automatically by Core Graphics: isEncrypted == true and isUnlocked == true. So the same document opened fine through openData and failed through openFile / openAsset as "Invalid PDF format". All three paths now test isUnlocked. Android was never affected.

  • An encrypted PDF now throws PdfPasswordProtectedException, not "Unknown error". On Android, PdfRenderer signals a password-protected document with SecurityException — a RuntimeException, so absent from the constructor's throws clause and easy to miss. Nothing caught it, so it fell through to the catch-all and surfaced as PlatformException(code: pdf_renderer, message: "Unknown error"), indistinguishable from any other failure. Both platforms now report the shared code PDF_PASSWORD_PROTECTED, which the Dart side turns into a typed, catchable exception. This is detection, not support — the plugin still cannot open an encrypted PDF (see TODO.md §2) — but a caller can now tell the user why instead of showing "unknown error".

    Unlike the WebP case above, this one is a true Exception rather than an Error: whether a PDF is encrypted is a property of the data, unknowable until it is read, so it cannot be avoided up front and catching it is correct.

  • Android depended on the wrong coroutines artifact. Messages.updateTexture returns to the platform thread with withContext(Dispatchers.Main), but the build declared kotlinx-coroutines-core, which has no Android main dispatcher — that lives in kotlinx-coroutines-android. It compiles either way and fails only at runtime (Module with the Main dispatcher had failed to initialize). It worked purely by accident: Flutter's own embedding pulls -android in transitively via androidx.lifecycle. That is Flutter's dependency to change, not a contract with us, so the plugin now declares kotlinx-coroutines-android itself (which depends on -core).

Toolchain #

  • Example app moved to Gradle 9.6.1 (from 9.1.0) and AGP 9.2.1 (from 9.0.1), both current. This also clears AGP's "recommend a newer Android Gradle plugin to use compile SDK 37" warning. kotlinx-coroutines stays at 1.10.2, which is still the latest release.

3.2.0+1 #

  • Docs only, no code change. Shortened the PdfViewPdfViewPinch migration step in the README; the detail it carried is already in 3.2.0 below.

3.2.0 #

Breaking #

Breaking, in a minor version — deliberate, while the fork still has essentially one consumer. If you use PdfView, pin pdfx_lite: 3.1.0+1 and migrate when convenient.

  • Removed PdfView and PdfController — the image-backed viewer. Use PdfViewPinch / PdfControllerPinch, which render through a platform texture and already zoom and page. Gone with them: PdfViewBuilders, PdfViewPageBuilder and PDfViewPageRenderer. The pinch viewer's own builders (PdfViewPinchBuilders) are unchanged, as are PdfPageNumber and the whole renderer API.

  • Removed the photo_view dependency, and it is no longer re-exported. PdfView was its only user — it wrapped PhotoViewGallery — and photo_view is unmaintained: last release 0.15.0 (April 2024), last commit September 2024, 119 open issues. It had no transitive dependencies, so it was not a resolution risk, but it was a Flutter upgrade away from being one, with nobody upstream to fix it. If you imported PhotoView, PhotoViewComputedScale or PhotoViewGalleryPageOptions through package:pdfx_lite/pdfx_lite.dart, depend on photo_view directly.

    pdfx_lite now has no third-party runtime dependencies beyond meta, synchronized and vector_math.

    Rebuilding the image-backed viewer yourself is a PageView of InteractiveViewers over PdfPageImageProvider, which is still exported — that is essentially what photo_view was doing.

3.1.0+1 #

  • Docs only, no code change. Trimmed the README (the bug-fix list lived here and in the CHANGELOG; the CHANGELOG keeps it) and linked the upstream reports.

3.1.0 #

Two bugs inherited from upstream, both still present in pdfx 2.9.2.

  • PdfViewPinch(scrollDirection: Axis.horizontal) was completely broken — it threw Unsupported operation: Infinity or NaN toInt on the first frame and rendered a blank page. The horizontal layout sets the document height to exactly the viewport height, so documentProgress's (docHeight - viewHeight) divisor is always zero; the resulting NaN then hit .round(), which throws. Vertical scrolling hit the same thing whenever a document happened to be no taller than the viewport. Now guarded: a document with nothing to scroll reports progress 0.0. Upstream has two partial patches open, neither merged: #602, #604 — both describe only the vertical case; the horizontal one was not reported.
  • Breaking-ish: PdfPage.render() now defaults to format: png, not jpeg. The default contradicted itself — the implementation (PdfPagePigeon.render) and both native sides already defaulted to PNG, and the doc comment said so, but the abstract PdfPage.render() that callers actually bind to said JPEG. Since backgroundColor is derived from the format, a plain render() also silently produced a white background instead of a transparent one. If you relied on the JPEG default, pass format: PdfPageImageFormat.jpeg explicitly. PdfView is unaffected — it always passed both arguments. Upstream: #581, unmerged.

3.0.0 #

First pdfx_lite release, forked from pdfx 2.9.2 (upstream's latest). 3.0.0, because the public API breaks and three platforms are gone — it is not compatible with any pdfx release. Versions below the line are upstream's history, kept for reference.

Breaking #

  • Android + iOS only. The Web (pdf.js), macOS and Windows renderers are gone, along with the CocoaPods podspec — SPM only. The method-channel implementation went with them; pigeon covers both remaining platforms.
  • Removed password: from PdfDocument.openFile / openAsset / openData. Only the web renderer ever honoured it — on mobile it was sent over the channel and ignored, so encrypted PDFs failed to open regardless.
  • Removed hasPdfSupport(). It was hardcoded true once web was gone.
  • Removed RgbaData and the in-memory getPixels(bytes:) path — both were reachable only from the web renderer. getPixels now takes a required String path, and a null path from the native renderer throws StateError.
  • PdfNotSupportException is now exported. It is thrown to callers (webp on iOS) but lived in an unexported file, so it could not be caught by type.
  • PdfViewPinch now uses Flutter's InteractiveViewer instead of a vendored 1670-line copy, which upstream carried for one custom knob: making a scroll event pan rather than zoom. Touch is unaffected — pan, pinch, fling and paging go through GestureDetector and never produce a scroll event, and Flutter's defaults match the copy's hardcoded ones (same friction constant, PanAxis.freealignPanAxis: false). The one change is a mouse wheel, which now zooms instead of panning — reachable only on a device with a mouse attached (or an emulator). In exchange the viewer picks up ~3 years of upstream fixes; the copy predated panAxis, trackpadScrollCausesScale and scaleFactor, and still used alignPanAxis, which Flutter has removed. PdfControllerPinch now extends Flutter's TransformationController, so it can be used anywhere one is expected.

Fixes not in upstream #

None of these have an upstream issue — they were found here, and are still live in pdfx 2.9.2.

  • Cropped rendering on Android was broken. renderPage took the crop width from the render width instead of cropWidth. Since the native code calls Bitmap.createBitmap(bmp, cropX, cropY, cropW, cropH), which requires cropX + cropW <= bitmap.width, any crop with cropX > 0 threw IllegalArgumentException — so render(cropRect:) failed outright unless the crop was flush to the left edge. iOS was always correct.
  • iOS renderPage called its completion twice on a render error, and signalled failure as completion(nil, nil) — a null reply with no error.
  • Data race in the iOS repositories. DocumentRepository / PageRepository were plain dictionaries written on the platform thread and read from the render queue, unsynchronised. Repository now holds an NSLock.
  • renderPage leaked a CoroutineScope per call on Android and never cancelled it, so a render outliving engine detach kept going and replied on a dead channel. One SupervisorJob scope now dies with the engine.

Native bridge #

  • Regenerated with pigeon 27: Kotlin, Swift and Dart from one schema. pigeon 4 could only emit Java and Obj-C, so the fork had been carrying 1479 lines of generated Pigeon.java plus a hand-translated Messages.swift that pigeon could no longer regenerate at all. Swift now gets native Int64/Double/Bool and Result-based completions instead of NSNumber, as! casts and AutoreleasingUnsafeMutablePointer<FlutterError?>.
  • pigeon is a dev dependency, so nothing reaches consumers.

Toolchain #

  • Requires Dart ^3.12 / Flutter >=3.44.
  • Android: minSdk 24, compileSdk 37, AGP 9 (Kotlin DSL), Gradle 9.6.1, Java/Kotlin target 17, kotlinx-coroutines 1.10.2. namespace is io.scer.pdfx. Bitmap.CompressFormat.WEBP (deprecated at API 30) gives way to WEBP_LOSSLESS / WEBP_LOSSY.
  • iOS: Swift Package Manager support, deployment target 15.0, and Swift 6 language mode (swift-tools-version: 6.2, needs Xcode 26+).
  • Dependencies dropped: flutter_web_plugins, web, universal_platform, uuid, extension, plugin_platform_interface. Only meta, photo_view, synchronized and vector_math remain.
  • Added a runnable example/ app (upstream's example/main.dart was a snippet, not a buildable project).

2.9.2 #

  • Fixed PdfViewPinch when compiling to WASM pull#586

2.9.1 #

2.9.0 #

  • Implemented document progress feature pull#537
  • Migrated to SurfaceProducer in PDFX pull#543
  • Updated Messages.kt pull#541
  • Removed device_info_plus dependency pull#544
  • Updated iOS and macOS projects to remove warnings pull#562
  • Updated device_info_plus version pull#536

2.8.0 #

2.7.0 #

  • Fixed pageSnapping option pull#435
  • Migrated to package:web pull#493
  • Bumped device_info_plus dependency to ^10.0.1 pull#487
  • Adjusted default zoom parameters pull#487
  • Fixed memory leak (Web) pull#484
  • Upgrade dependencies

2.6.0 #

  • Flutter 3.16 compatibility

2.5.0 #

  • Upgrade dependencies

2.4.0 #

  • Upgrade dependencies
  • Dart 3, Flutter 3.10 compatibility pull#404
  • Transfer Pdf support check from viewer to renderer pull#392
  • Added reverse option in PdfView pull#412
  • Fixup rendering issues in chromium based web-browsers pull#402

2.3.0 #

  • Added option forPrint in image render pull#301
  • Added password support (web only) pull#354
  • Updated dependencies

2.2.0 #

  • Upgrade dependency device_info_plus to v4
  • Fixed flutter 3.0 build
  • Fixed web install script
  • Fixed some bugs

2.1.0 #

2.0.1+2 #

  • Fixed broken links at pub.dev
  • Fixed readme
  • Update pdfjs version in installation script

2.0.1+1 #

  • Update readme

2.0.1 #

  • Fixed android launch

2.0.0 #

  • Provide more docs
  • Fixed windows support
  • Added builders argument for PdfViewPinch & PdfView. Example:
PdfViewPinch(
  builders: PdfViewPinchBuilders<DefaultBuilderOptions>(
    options: const DefaultBuilderOptions(
      loaderSwitchDuration: const Duration(seconds: 1),
      transitionBuilder: SomeWidget.transitionBuilder,
    ),
    documentLoaderBuilder: (_) =>
        const Center(child: CircularProgressIndicator()),
    pageLoaderBuilder: (_) =>
        const Center(child: CircularProgressIndicator()),
    errorBuilder: (_, error) => Center(child: Text(error.toString())),
    builder: SomeWidget.builder,
  ),
)
  • Added widget PdfPageNumber for show actual page number & all pages count. Example:
PdfPageNumber(
  controller: _pdfController,
  // When `loadingState != PdfLoadingState.success`  `pagesCount` equals null_
  builder: (_, state, loadingState, pagesCount) => Container(
    alignment: Alignment.center,
    child: Text(
      '$page/${pagesCount ?? 0}',
      style: const TextStyle(fontSize: 22),
    ),
  ),
)
  • Added listenable page number pageListenable in PdfController & PdfControllerPinch. Example:
ValueListenableBuilder<int>(
  valueListenable: controller.pageListenable,
  builder: (context, actualPageNumber, child) => Text(actualPageNumber.toString()),
)
  • Added listenable loading state loadingState in PdfController & PdfControllerPinch. Example:
ValueListenableBuilder<PdfLoadingState>(
  valueListenable: controller.loadingState,
  builder: (context, loadingState, loadingState) => (){
    switch (loadingState) {
      case PdfLoadingState.loading:
        return const CircularProgressIndicator();
      case PdfLoadingState.error:
        return  const Text('Pdf load error');
      case PdfLoadingState.success:
        return const Text('Pdf loaded');
    }
  }(),
)
  • Removed documentLoader, pageLoader, errorBuilderm loaderSwitchDuration arguments from PdfViewPinch & PdfView
  • Removed pageSnapping, physics arguments from PdfViewPinch
  • Rename PdfControllerPinch page control methods like a PdfController control names

1.0.1+1 #

  • Updated readme

1.0.1 #

  • Fixed platforms plugin

1.0.0 #

  • Initial release
0
likes
160
points
173
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

Minimal, legacy-free PDF rendering & viewing for Flutter (Android + iOS) — no CocoaPods, SPM-only, no web/desktop renderers. Replacement for pdfx.

Repository (GitHub)
View/report issues

License

MIT (license)

Dependencies

flutter, meta, synchronized, vector_math

More

Packages that depend on pdfx_lite

Packages that implement pdfx_lite