Skip to content

PDF Viewer

The FioriPDFViewer is a composable layout used to display a chosen PDF file. It is implemented based on PdfRenderer, so displayed content cannot be selected and is read-only.

Setting up the PDF Viewer

Create a PDF viewer control:

fun FioriPDFViewer(
    modifier: Modifier,
    file: File, // The PDF file to be displayed.
)

Note that the viewer is implemented based on PdfRenderer, which takes a ParcelFileDescriptor object as input. So developers need to make sure the file object fed to the FioriPDFViewer can be converted to ParcelFileDescriptor by ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY), otherwise, the viewer will fail to open the PDF file on creating PdfRenderer internally and terminate subsequent rendering.

page

Setting up the PDF Viewer for Encrypted PDF Files

When creating a PDF viewer control against an encrypted PDF file, developers can also use some additional parameters in the viewer to decrypt the file.

fun FioriPDFViewer(
    modifier: Modifier = Modifier.fillMaxSize(),
    file: File,
    printer:Printer = Printer.rememberPrinter(), // Use the printer to allow developers to print without needing to handle passwords.
    password:String? = null, // Use the password to decrpyt the file. It is regared not protected behind password if it is set to null.
    decodedCallback:()->Unit = {}, // When the PDF file is successfully decrypted by password, this callback will be triggered.
    invalidPasswordCallback:()->Unit = {} // When the password is wrong for the encrypted PDF file, this callback will be triggered.
)

There is also a version with an integrated password-input screen. Developers don't need to manage the password themselves:

@Composable
fun FioriPDFViewer(
    modifier: Modifier = Modifier.fillMaxSize(),
    file: File,
    printer: Printer = Printer.rememberPrinter(),
    errorCallback:(String?)->Unit = {}, The callback triggers if the system fails to parse the file as a PDF.
    cancelCallback:()->Unit, // When the document is encrypted, the callback can be triggered when user clicks the cancel button in the password-input screen.
)

Interactions with the PDF Viewer

  • Users can zoom in and zoom out using the pinch gesture.

zoom

  • Scrolling is supported at any zoom level. If a user continues to scroll up or down when the bound of the page reaches the bound of the layout, the PDF viewer will display the previous or next page, respectively. Dragging on the scroll bar is also supported so that the user can easily navigate to other parts of the PDF file. flipping

  • Links are interactable in the FioriPDFViewer. On clicking internal links, the viewer will navigate to the corresponding page bound with the link. On clicking the hyperlink, the viewer will try to start an activity by default, with an intent along with the URI of the hyperlink, so that the package manager service of the Android system will try to launch the system browser to handle the URI.

  • Thumbnails of pages can be displayed when a user long-clicks anywhere in the page.

thumbnail

In this mode, the viewer will navigate to whichever page the user clicks.

Users can print PDF documents by invoking the print function provided in the PDF viewer.

print(
    context = context, // Application context used to open print service.
    pdfFileDescriptor = fd, // PDF file descriptor.
    password = null, // Password to decrypt the PDF file. Setting it to null implies the file is not encrypted.
    decodedCallback:()->Unit = {}, //Once the PDF file is successfully decrypted with password, this callback will be triggered.
    invalidPasswordCallback:()->Unit = {} // If the password is not correct, this callback will be triggered.
)

Customizations

There are several ProvidableCompositionLocal values used in the implementation of the FioriPDFViewer. Developers can provide their own implementations to customize the corresponding behaviors.

  • LocalBottomPadding denotes the bottom padding that will be applied to the preview screen and the index indicator. In some cases, the FioriPDFViewer can be overlapped by the navigation bar on the bottom of the screen. In order to prevent content overlap, a constant padding is explicitly applied to the bottom of the PDF content using LocalBottomPadding. By default, it is 50.dp.
val LocalBottomPadding= staticCompositionLocalOf {
    50.dp
}
  • LocalFioriPDFUriHandler provides the handler that handles hyperlinks that the user clicks.
val LocalFioriPDFUriHandler: ProvidableCompositionLocal<UriHandler?> = staticCompositionLocalOf {
    null
}

When a user clicks the hyperlinks in the FioriPDFViewer, the fun openUri(uri: String) in UriHandler will be invoked. By default, the handler will try to start an activity with an intent, along with the uri provided in the openUri function.

  • LocalScrollbarWidth defines the visible width of the scroll bar in the viewer. Note that the width is only the visible width. The width of the actual interactive area is twice this size.
val LocalScrollbarWidth = staticCompositionLocalOf {
    20.dp
}

Last update: August 19, 2025