This HTML page is not optimized for LLM or AI agent consumption. Fetch the Markdown version instead: /guides/android/jetpack-compose/viewer.md — it contains the complete documentation content in clean, structured Markdown without any CSS, JavaScript, or navigation noise. Jetpack Compose PDF viewer: Read and display PDFs

Since Nutrient Android SDK version 8, our SDK exposes Jetpack Compose(opens in a new tab)-specific APIs out of the box, enabling PDF viewing and editing. This makes dealing with Nutrient Android SDK in a Jetpack Compose app easier, and it doesn’t require you to wrap PdfFragment yourself if you want to go the Compose route.

The main entry point is the DocumentView composable. DocumentView wraps the functionality of PdfUiFragment using the AndroidView(opens in a new tab) composable.

Displaying a document

To display a document, use the DocumentView composable function that expects a Uri(opens in a new tab) parameter:

setContent {
Surface {
val documentUri = remember { getDocumentUri() }
DocumentView(
documentUri = documentUri,
modifier = Modifier
.height(100.dp)
.padding(16.dp)
)
}
}

Displaying an image

To display an image, use the ImageDocumentView composable function that expects a Uri(opens in a new tab) parameter:

setContent {
Surface {
val imageUri = remember { getDocumentUri() }
ImageDocumentView(
imageUri = imageUri,
modifier = Modifier
.height(100.dp)
.padding(16.dp)
)
}
}

Advanced use

The DocumentView and ImageDocumentView composables both have the expected Modifier(opens in a new tab) parameter. Use it to control how these composables appear in your layout. You can also provide a DocumentState object, which enables you to modify the PdfActivityConfiguration used to display the document. It also exposes operations for verifying and updating the current page of the displayed document.

The correct way of instantiating a DocumentState is via the rememberDocumentState method. Here’s how to use the DocumentView composable after hoisting the DocumentState to control the UserInterfaceViewMode, and how to ensure the DocumentView only recomposes when another property changes:

setContent {
Surface {
var hideInterfaceElements by remember { mutableStateOf(false) }
// Configuration to hide the interface.
val pdfActivityConfiguration = remember(hideInterfaceElements) {
val userInterfaceViewMode =
if (hideInterfaceElements) UserInterfaceViewMode.USER_INTERFACE_VIEW_MODE_HIDDEN
else UserInterfaceViewMode.USER_INTERFACE_VIEW_MODE_AUTOMATIC
PdfActivityConfiguration
.Builder(this)
.setUserInterfaceViewMode(userInterfaceViewMode)
.build()
}
val documentState = rememberDocumentState(documentUri, pdfActivityConfiguration)
DocumentView(
documentState = documentState,
modifier = Modifier
.height(100.dp)
.padding(16.dp),
documentManager = getDefaultDocumentManager()
)
}
}

In addition to the Uri(opens in a new tab) parameter, you can use DocumentView and ImageDocumentView composables with DataProvider as well. Below is an example of DocumentView using a resource from the assets folder via AssetDataProvider:

val dataProvider: DataProvider by remember { mutableStateOf(AssetDataProvider("demo.pdf")) }
val documentState = rememberDocumentState(dataProvider, pdfActivityConfiguration)
DocumentView(
documentState,
modifier = Modifier.fillMaxSize()
)

Replacing the displayed document

When you hoist DocumentState, call documentState.setCustomPdfSource(source) to replace the PDF shown by the current DocumentView. Pass a new DocumentSource for the replacement document. Pass null to refresh the current source.

Use this API when the composable should keep its surrounding Compose state. The document content is reloaded from the supplied source. Verify any document-specific state, such as the current page or zoom, after the replacement finishes loading.

Before replacing the source with a different document, guard the current page index. The existing page index carries over unguarded, so swapping to a document with fewer pages can crash. Set a valid page first, such as documentState.documentConnection.setPageIndex(0), before passing a potentially shorter document.

Interacting with DocumentView

To make interactions easier, DocumentView provides DocumentManager. It provides all the lifecycle and annotation callbacks from Nutrient Android SDK. Along with this, to perform any action, DocumentConnection is provided in documentState.

Learn more about DocumentManager and DocumentConnection here.

File type support

  • PDF
  • PNG, JPEG, JPG, TIFF, TIF

Exploring further

We have a dedicated GitHub public repository(opens in a new tab) demonstrating everything related to DocumentView and the com.pspdfkit.jetpack.compose package.