Blog Infos
Author
Published
Topics
, , , ,
Author
Published
Header Image

In this article, we will explore the new library introduced under AndroidX ☂️ called PdfViewer

The first alpha version of this library was published on August 7, 2024.

Current version is 1.0.0-alpha02

Major limitation : Currently it support only Android V [SDK 35]

It provides us PdfViewerFragment that we can use in our application to show/view the PDF files.

Here is one of the most common solutions used by Android applications 👇
// create intent
val pdfIntent = Intent(Intent.ACTION_VIEW).apply {
    setDataAndType(pdfUri, "application/pdf")
    setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY)
}

// try to open the intent - If there is any activity that can handle it 
try {
    startActivity(pdfIntent)
} catch (activityNotFoundException: ActivityNotFoundException) {
    Log.e(TAG, "onCreate: ${activityNotFoundException.message}")
}
Implementation
  • We will go through the compose-based implementation

Add dependency

// version catalog
pdf-viewer-fragment = {module = "androidx.pdf:pdf-viewer-fragment", version.ref = "pdfViewerFragment"}

// app level build.gradle
implementation(libs.pdf.viewer.fragment)

Create a launcher for ActivityResult using rememberLauncherForActivityResult

  • We will use built-in ActivityResultContracts.GetContent() to pick a pdf file 🗒️
var pdfURI: Uri? by remember { mutableStateOf(null) }

val pickFileLauncher =
    rememberLauncherForActivityResult(ActivityResultContracts.GetContent()) { uri: Uri? ->
        if(uri != null) {
            pdfURI = uri
        }
    }

Compose based UI

Column(modifier = Modifier
    .safeContentPadding()
    .padding(32.dp)) {

    ElevatedButton(
        onClick = { pickFileLauncher.launch("application/pdf") },
        modifier = Modifier.fillMaxWidth()) {
        Row(verticalAlignment = Alignment.CenterVertically) {
            Icon(Icons.Default.Add, contentDescription = null)
            Spacer(modifier = Modifier.size(ButtonDefaults.IconSpacing))
            Text("Pick PDF")
        }
    }

// Show PdfFragment when pdfURI is not null
    pdfURI?.let {
        AndroidViewBinding(
            factory = PdfFragmentViewBinding::inflate,
            modifier = Modifier
                .padding(horizontal = 16.dp)
        ) {
val fragment = fragmentContainerPdfViewer.getFragment<PdfViewerFragment>()
            fragment.documentUri = uriI
        }

    }

}
  • On button’s click, we launch the pickFileLauncher, and update the pdfURI based on the result

Initial UI state

Job Offers

Job Offers

There are currently no vacancies.

OUR VIDEO RECOMMENDATION

No results found.

Jobs

var pdfURI: Uri? by remember { mutableStateOf(null) }
  • pdfURI is mutableState so whenever it gets changed it automatically updates the documentUri property of the fragment
pdfURI?.let {
        AndroidViewBinding(
            factory = PdfFragmentViewBinding::inflate,
            modifier = Modifier
                .padding(horizontal = 16.dp)
        ) {
            val fragment = fragmentContainerPdfViewer.getFragment<PdfViewerFragment>()
            fragment.documentUri = uriI
        }
        
}

We can also use the new Composable introduced in fragment version 1.8.0 called AndroidFragment

  • Currently, PdfViewerFragment is not working with this composable due to API limitations, but hopefully, these issues will be resolved in future releases.
pdfURI?.let {
    Log.d(TAG, "Selected URI: $pdfURI")
    AndroidFragment<PdfViewerFragment>(
        arguments = bundleOf("documentUri" to pdfURI),
        modifier = Modifier.fillMaxSize()
    ) { pdfViewerFragment ->
        Log.d(TAG, "URI ${pdfViewerFragment.documentUri}")
    }

 

Stay in touch 🤝

https://www.linkedin.com/in/navczydev/

https://twitter.com/navczydev?source=post_page—–b31cd5398ac4——————————–

https://github.com/navczydev?source=post_page—–b31cd5398ac4——————————–

References

YOU MAY BE INTERESTED IN

YOU MAY BE INTERESTED IN

blog
It’s one of the common UX across apps to provide swipe to dismiss so…
READ MORE
blog
In this part of our series on introducing Jetpack Compose into an existing project,…
READ MORE
blog
In the world of Jetpack Compose, where designing reusable and customizable UI components is…
READ MORE
blog

How to animate BottomSheet content using Jetpack Compose

Early this year I started a new pet project for listening to random radio…
READ MORE
Menu