A lightweight Android PDF viewer library powered by Mozilla's PDF.js, offering seamless PDF rendering and interactive features. Supports both Jetpack Compose and Xml.
For setup see Setup
For Jetpack Compose examples see Jetpack Compose Examples
<com.bhuvaneshw.pdf.PdfViewer
android:id="@+id/pdf_viewer"
android:layout_width="match_parent"
android:layout_height="match_parent" />val pdfViewer = findViewById<PdfViewer>(R.id.pdf_viewer)
val source = "asset://sample.pdf"
// Kotlin
pdfViewer.onReady {
load(source)
}// Java
PdfUtil.onReady(pdfViewer, () -> {
pdfViewer.load(source);
});<com.bhuvaneshw.pdf.PdfViewer
android:id="@+id/pdf_viewer"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:containerBackgroundColor="@android:color/transparent" />pdfViewer.onReady {
load(source)
}<com.bhuvaneshw.pdf.ui.PdfViewerContainer
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/pdf_viewer_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity2">
<com.bhuvaneshw.pdf.PdfViewer
android:id="@+id/pdf_viewer"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</com.bhuvaneshw.pdf.ui.PdfViewerContainer><com.bhuvaneshw.pdf.ui.PdfViewerContainer xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/pdf_viewer_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity2">
<!-- id is mandatory, if not random int will be assigned by PdfViewerContainer-->
<com.bhuvaneshw.pdf.ui.PdfToolBar
android:id="@+id/pdf_tool_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<com.bhuvaneshw.pdf.PdfViewer
android:id="@+id/pdf_viewer"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<com.bhuvaneshw.pdf.ui.PdfScrollBar
android:id="@+id/pdf_scroll_bar"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</com.bhuvaneshw.pdf.ui.PdfViewerContainer>val pdfToolBar = findViewById<PdfToolBar>(R.id.pdf_tool_bar)
pdfToolBar.back.setImageResource(com.bhuvaneshw.pdf.ui.R.drawable.outline_arrow_back_24)<com.bhuvaneshw.pdf.ui.PdfViewerContainer xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<!-- id is mandatory, if not random int will be assigned by PdfViewerContainer-->
<com.bhuvaneshw.pdf.ui.PdfToolBar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:contentColor="@color/md_theme_onBackground" />
<com.bhuvaneshw.pdf.PdfViewer
android:id="@+id/pdf_viewer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/md_theme_primaryContainer"
app:containerBackgroundColor="@android:color/transparent" />
<com.bhuvaneshw.pdf.ui.PdfScrollBar
android:id="@+id/pdf_scroll_bar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:contentColor="@color/md_theme_onBackground"
app:handleColor="@color/md_theme_background" />
</com.bhuvaneshw.pdf.ui.PdfViewerContainer><com.bhuvaneshw.pdf.ui.PdfScrollBar
android:id="@+id/pdf_scroll_bar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:useVerticalScrollBarForHorizontalMode="true" />val pdfScrollBar = findViewById<PdfScrollBar>(R.id.pdf_scroll_bar)
pdfScrollBar.interactiveScrolling = false<com.bhuvaneshw.pdf.ui.PdfViewerContainer xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/pdf_viewer_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity2">
<!-- id is mandatory, if not random int will be assigned by PdfViewerContainer-->
<com.bhuvaneshw.pdf.ui.PdfToolBar
android:id="@+id/pdf_tool_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<com.bhuvaneshw.pdf.PdfViewer
android:id="@+id/pdf_viewer"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<com.bhuvaneshw.pdf.ui.PdfScrollBar
android:id="@+id/pdf_scroll_bar"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<LinearLayout
android:id="@+id/loading_indicator"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/pdf_tool_bar"
android:background="@android:color/white"
android:gravity="center"
android:visibility="gone">
<ProgressBar
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
</com.bhuvaneshw.pdf.ui.PdfViewerContainer>val pdfContainer = findViewById<PdfViewerContainer>(R.id.pdf_viewer_container)
val loadingIndicator = findViewById<LinearLayout>(R.id.loading_indicator)
pdfContainer.setAsLoadingIndicator(loadingIndicator)<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<com.bhuvaneshw.pdf.ui.PdfToolBar
android:id="@+id/pdf_tool_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:contentColor="@color/md_theme_onBackground" />
<!-- add below toolbar-->
<com.bhuvaneshw.pdf.PdfViewer
android:id="@+id/pdf_viewer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/toolbar"
android:background="@color/md_theme_primaryContainer"
app:containerBackgroundColor="@android:color/transparent" />
<!-- set align parent right, don't add below toolbar-->
<com.bhuvaneshw.pdf.ui.PdfScrollBar
android:id="@+id/pdf_scroll_bar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
app:contentColor="@color/md_theme_onBackground"
app:handleColor="@color/md_theme_background" />
</RelativeLayout>val pdfViewer = findViewById<PdfViewer>(R.id.pdf_viewer)
val source = "asset://sample.pdf"
val pdfScrollBar = findViewById<PdfScrollBar>(R.id.pdf_scroll_bar)
val pdfToolBar = findViewById<PdfToolBar>(R.id.pdf_tool_bar)
pdfToolBar.setupWith(pdfViewer)
pdfScrollBar.setupWith(pdfViewer, pdfToolBar)
pdfViewer.onReady {
load(source)
toolbar.setFileName(fileName) // or toolbar.setTitle(title)
}You can add listener with extension like
pdfViewer.addListener(onPageLoadFailed = { // Specific listener (Extension functions)
})or
pdfViewer.addListener(object: PdfListener {
// implement required methods
})Note
For Download listener see implementation in PdfViewerActivity.kt