{"id":15040804,"url":"https://github.com/afreakyelf/pdf-viewer","last_synced_at":"2026-03-16T07:26:06.133Z","repository":{"id":43383128,"uuid":"278914823","full_name":"afreakyelf/Pdf-Viewer","owner":"afreakyelf","description":"A Lightweight PDF Viewer Android library which only occupies around 80kb while most of the Pdf viewer occupies up to 16MB space.","archived":false,"fork":false,"pushed_at":"2025-05-10T21:29:55.000Z","size":1238,"stargazers_count":966,"open_issues_count":34,"forks_count":204,"subscribers_count":14,"default_branch":"master","last_synced_at":"2025-05-10T22:25:20.200Z","etag":null,"topics":["android","android-application","android-pdf","android-pdfviewer","androidpdfviewer","androidsdk","jetpack-components","jetpack-compose","jetpackcompose","kotlin","library","lightweight-pdf-viewer-android","pdf","pdf-viewer","pdfviewer","small-size-pdfviewer"],"latest_commit_sha":null,"homepage":"https://afreakyelf.github.io/Pdf-Viewer/","language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/afreakyelf.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null},"funding":{"github":null,"patreon":null,"open_collective":null,"ko_fi":null,"tidelift":null,"community_bridge":null,"custom":["https://www.buymeacoffee.com/afreakyelf","https://liberapay.com/afreakyelf"]}},"created_at":"2020-07-11T17:58:09.000Z","updated_at":"2025-05-10T21:29:59.000Z","dependencies_parsed_at":"2024-01-16T23:30:48.050Z","dependency_job_id":"7195d759-40da-48e6-9cf3-65857d7ff263","html_url":"https://github.com/afreakyelf/Pdf-Viewer","commit_stats":null,"previous_names":[],"tags_count":41,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/afreakyelf%2FPdf-Viewer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/afreakyelf%2FPdf-Viewer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/afreakyelf%2FPdf-Viewer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/afreakyelf%2FPdf-Viewer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/afreakyelf","download_url":"https://codeload.github.com/afreakyelf/Pdf-Viewer/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254227605,"owners_count":22035668,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["android","android-application","android-pdf","android-pdfviewer","androidpdfviewer","androidsdk","jetpack-components","jetpack-compose","jetpackcompose","kotlin","library","lightweight-pdf-viewer-android","pdf","pdf-viewer","pdfviewer","small-size-pdfviewer"],"created_at":"2024-09-24T20:45:06.139Z","updated_at":"2026-03-16T07:26:06.127Z","avatar_url":"https://github.com/afreakyelf.png","language":"Kotlin","funding_links":["https://www.buymeacoffee.com/afreakyelf","https://liberapay.com/afreakyelf","https://www.paypal.com/paypalme/afreakyelf"],"categories":[],"sub_categories":[],"readme":"\u003ch1 align=\"center\"\u003ePdf Viewer For Android\u003c/h1\u003e\n\n\u003cp align=\"center\"\u003e\nA Simple PDF Viewer library which only occupies around \u003cb\u003e80kb\u003c/b\u003e while most of the Pdf viewer occupies upto \u003cb\u003e16MB\u003c/b\u003e space.\n\u003cbr\u003e\n\u003cbr\u003e\n\u003c/p\u003e\n\u003cp float=\"left\"\u003e\n  \u003cimg src=\"https://github.com/afreakyelf/Pdf-Viewer/assets/38572147/e310060c-bea2-42ee-b02a-3758f3122e05\" width=\"199\" /\u003e\n  \u003cimg src=\"https://github.com/afreakyelf/Pdf-Viewer/assets/38572147/13f64593-7627-48bc-b573-54cebb0651b2\" width=\"199\" /\u003e\n  \u003cimg src=\"https://github.com/afreakyelf/Pdf-Viewer/assets/38572147/fa6a0ff9-11dd-4087-bf7e-d4ba6795386c\" width=\"199\" /\u003e\n  \u003cimg src=\"https://github.com/afreakyelf/Pdf-Viewer/assets/38572147/babde964-5373-4d03-85ad-1b8c2cc0ab29\" width=\"199\" /\u003e\n  \u003cimg src=\"https://github.com/afreakyelf/Pdf-Viewer/assets/38572147/4344c962-88f7-4be4-8935-50370ad6752d\" width=\"199\" /\u003e\n\n\u003c/p\u003e\n\n\n[![Maven Central](https://img.shields.io/maven-central/v/io.github.afreakyelf/Pdf-Viewer.svg)](https://search.maven.org/artifact/io.github.afreakyelf/Pdf-Viewer) [![License](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/Apache-2.0) ![](https://img.shields.io/github/forks/afreakyelf/Pdf-Viewer?label=Forks)\n![](https://img.shields.io/github/stars/afreakyelf/Pdf-Viewer?label=Stars\u0026color=9cf) ![Visitors](https://api.visitorbadge.io/api/visitors?path=https%3A%2F%2Fgithub.com%2Fafreakyelf%2FPdf-Viewer\u0026label=Visitors\u0026countColor=%23263759\u0026style=flat) [![CodeFactor](https://www.codefactor.io/repository/github/afreakyelf/pdf-viewer/badge)](https://www.codefactor.io/repository/github/afreakyelf/pdf-viewer) ![Discord](https://img.shields.io/discord/1213235452908408943?style=flat\u0026label=Join%20discord\u0026link=https%3A%2F%2Fdiscord.gg%2FK3u4DscdWW)\n\n\n## [New] Join our Discord Community [here](https://discord.gg/342ZFHX9mK)!\n\n\n## ✨ Major Enhancements in Our PDF Viewer Library ✨\nHello Developers! We're thrilled to share some significant enhancements we've made to our PDF viewer library. We've fine-tuned several aspects to enhance your experience and ensure top-notch performance and security. Here's what's new:\n\n- ### Jetpack Compose Ready 🚀\n  Step into the future with Jetpack Compose compatibility. Integrating our PDF viewer in Compose projects is now effortless, thanks to the PdfRendererViewCompose composable function.\n- ### Turbocharged Performance 🏎️\n  We've optimized performance to handle PDFs more efficiently, ensuring swift and smooth operations, even with large documents.\n- ### Local and on device files 📁\n  We have made it better and smooth with how local files are handled now, with latest permission policies. \n- ### Seamless Orientation Adaptation 🔄\n    Our library now smartly preserves your page position during orientation changes, ensuring uninterrupted reading sessions. \n- ### Enhanced File Path Security 🔐\n    Security just got stronger. We've revamped our file path handling to provide robust protection against directory traversal attacks, keeping your data safer than ever.\n- ### Streamlined Caching System 💾\n    Experience efficiency at its best! Our refined caching strategy smartly manages storage, retaining only the most recent PDF file to optimize performance and space usage.\n- ### Discreet Screenshot Prevention Feature 🚫📸\n    Privacy matters. Our new screenshot-blocking feature enhances data confidentiality in your app, keeping sensitive information secure from prying eyes.\n- ### Flexible UI Customization ✨\n    Your design, your rules. Enjoy complete freedom in customizing the PDF viewer's interface, ensuring a perfect match with your app's style and theme. Render the view directly in your screen now.\n- ### 'NoActionBar' Theme Compatibility 🎨\n    Seamless aesthetics, no matter the theme. Our library now gracefully integrates with 'NoActionBar' themes, ensuring a cohesive and appealing user interface.\n\nStay tuned as we continue to innovate and improve. Happy coding, and let's keep creating amazing experiences together!\n\n## How to integrate into your app? ⚙️\n\nWe have migrated our library to Maven Central for easier integration and better reliability. To use the Pdf Viewer library in your project, add the following dependency to your `build.gradle` file:\n\n#### Latest version: ![](https://img.shields.io/maven-central/v/io.github.afreakyelf/Pdf-Viewer.svg) without 'v'\n\n### Groovy DSL\n```gradle\ndependencies {\n    // Replace 'latest-version' with the actual latest version number\n    implementation 'io.github.afreakyelf:Pdf-Viewer:latest-version'\n}\n```\n### Kotlin DSL\n```gradle\ndependencies {\n    // Replace 'latest-version' with the actual latest version number\n    implementation(\"io.github.afreakyelf:Pdf-Viewer:latest-version\")\n}\n```\n\n### Requirements:\n- Minimum SDK version: 21\n- Compile \u0026 Target SDK version: 35 (updated since version 2.2.0)\n\n### Java App Integration\n\nIf your Android app is written in **Java** (not Kotlin) and you encounter a crash at startup with:\n\n\u003e `java.lang.NoClassDefFoundError: Failed resolution of: Landroidx/lifecycle/ProcessLifecycleOwner$initializationListener$1`\n\n**The recommended fix is to update to the latest version of Pdf-Viewer**, which adds version\nconstraints for `lifecycle-process` and `lifecycle-runtime-ktx` (requiring a minimum of 2.8.7\nduring dependency resolution) and includes consumer ProGuard rules to prevent minifiers from\nstripping these classes.\n\nIf you still see this crash after updating to the latest version of Pdf-Viewer, there are two possible causes with different remedies:\n\n- **Dependency misresolution** (wrong `lifecycle-process` version resolved): Force the correct version in your `build.gradle`:\n\n#### Groovy DSL\n```gradle\ndependencies {\n    implementation 'io.github.afreakyelf:Pdf-Viewer:latest-version'\n\n    // Force the correct lifecycle-process version if your dependency graph resolves an older one.\n    implementation 'androidx.lifecycle:lifecycle-process:2.8.7'\n    implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.8.7'\n}\n```\n\n#### Kotlin DSL\n```gradle\ndependencies {\n    implementation(\"io.github.afreakyelf:Pdf-Viewer:latest-version\")\n\n    // Force the correct lifecycle-process version if your dependency graph resolves an older one.\n    implementation(\"androidx.lifecycle:lifecycle-process:2.8.7\")\n    implementation(\"androidx.lifecycle:lifecycle-runtime-ktx:2.8.7\")\n}\n```\n\n- **R8/minifier stripping** (classes removed during shrinking): The library ships consumer rules in `consumer-rules.pro` that AGP/R8 automatically merges into your build. These rules will not take effect if `minifyEnabled false` is set for your release build type, if you are using a non-AGP shrinker pipeline, or if shrinker warnings are treated as errors and abort the build. In those cases, add the rules manually to your app's `proguard-rules.pro`:\n\n```proguard\n-keep,allowobfuscation class androidx.lifecycle.ProcessLifecycleOwner { *; }\n-keep,allowobfuscation class androidx.lifecycle.ProcessLifecycleOwner$* { *; }\n```\n\n\u003e **Note:** `kotlin-stdlib` and the lifecycle artifacts are included as transitive dependencies\n\u003e by the library and do not need to be declared separately in most cases.\n\n## How to use the library?\nNow you have integrated the library in your project but **how do you use it**? Well it's really easy. Just launch the intent with in following way: (Refer to [MainActivity.kt](https://github.com/afreakyelf/Pdf-Viewer/blob/master/app/src/main/java/com/rajat/sample/pdfviewer/MainActivity.kt) for more details.)\n\n### Prerequisites\nEnsure the library is included in your project's dependencies.\n\n### Launching PDF Viewer\n\n#### Opening PDF from a URL\nTo display a PDF from a URL, use the following code:\n\n```kotlin\n/* Parameters:\n- context: The context of your activity.\n- pdfUrl: URL of the PDF to be displayed.\n- pdfTitle: Title of the PDF document.\n- saveTo: Determines how to handle saving the PDF (e.g., ASK_EVERYTIME prompts the user each time).\n- enableDownload: Enables downloading of the PDF. */\n\nPdfViewerActivity.launchPdfFromUrl(\n    context = this,\n    pdfUrl = \"your_pdf_url_here\",\n    pdfTitle = \"PDF Title\",\n    saveTo = saveTo.ASK_EVERYTIME,\n    enableDownload = true\n)\n```\n\n#### Opening PDF from Local Storage\nTo open a PDF stored in local storage:\n\n```kotlin\n/* Parameters:\n- path: File path or URI of the local PDF.\n- fromAssets: Set to false when loading from local storage. // FALSE by default\n*/\n\nPdfViewerActivity.launchPdfFromPath(\n    context = this,\n    path = \"your_file_path_or_uri_here\",\n    pdfTitle = \"Title\",\n    saveTo = saveTo.ASK_EVERYTIME,\n    fromAssets = false\n)\n```\n\n#### Opening PDF from Assets\nTo open a PDF from the app's assets folder:\n\n```kotlin\n/* Parameters:\n- path: File path or URI of the local PDF.\n- fromAssets: Set to true when loading from assets.\n*/\n\nPdfViewerActivity.launchPdfFromPath(\n  context = this,\n  path = \"file_name_in_assets\",\n  pdfTitle = \"Title\",\n  saveTo = saveTo.ASK_EVERYTIME,\n  fromAssets = true\n)\n```\n\n#### Loading PDF in a View\nLoad a PDF directly into a view:\n\nAdd PDF render view in your layout file\n\n```xml\n\u003ccom.rajat.pdfviewer.PdfRendererView\n    android:id=\"@+id/pdfView\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    app:pdfView_divider=\"@drawable/pdf_viewer_divider\"\n    app:pdfView_showDivider=\"false\" /\u003e\n```\nand in your kotlin file\n```kotlin\nbinding.pdfView.initWithUrl(\n  url = \"your_pdf_url_here\",\n  lifecycleCoroutineScope = lifecycleScope,\n  lifecycle = lifecycle\n)\n\n```\n\n#### Using with Jetpack Compose\nFor Jetpack Compose, utilize PdfRendererViewCompose:\n\n```kotlin\nPdfRendererViewCompose(\n    source = PdfSource.Remote(\"your_pdf_url_here\"),\n    lifecycleOwner = LocalLifecycleOwner.current,\n    modifier = Modifier,\n    headers = HeaderData(mapOf(\"Authorization\" to \"123456789\")),\n    statusCallBack = object : PdfRendererView.StatusCallBack {\n                // Override functions here\n    },\n    zoomListener = object : PdfRendererView.ZoomListener {\n                // Override functions here\n        override fun onZoomChanged(isZoomedIn: Boolean, scale: Float) {\n                    TODO(\"Not yet implemented\")\n         }\n     }\n)\n```\n\nThat's all you need to integrate PDF rendering in your Compose application.\n\n### Track PDF Load \u0026 Zoom Events \nYou can monitor download progress, rendering success, page changes, and zoom state using the following callbacks:\n\n#### PDF Load Status\nUse the `statusListener` to get callbacks on PDF lifecycle events:\n\n```kotlin\nbinding.pdfView.statusListener = object : PdfRendererView.StatusCallBack {\n    override fun onPdfLoadStart() {\n        Log.i(\"PDF Status\", \"Loading started\")\n    }\n\n    override fun onPdfLoadProgress(progress: Int, downloadedBytes: Long, totalBytes: Long?) {\n        Log.i(\"PDF Status\", \"Download progress: $progress%\")\n    }\n\n    override fun onPdfLoadSuccess(absolutePath: String) {\n        Log.i(\"PDF Status\", \"Load successful: $absolutePath\")\n    }\n\n    override fun onError(error: Throwable) {\n        Log.e(\"PDF Status\", \"Error loading PDF: ${error.message}\")\n    }\n\n    override fun onPageChanged(currentPage: Int, totalPage: Int) {\n        Log.i(\"PDF Status\", \"Page changed: $currentPage / $totalPage\")\n    }\n  \n    override fun onPdfRenderStart() {\n      Log.i(\"PDF Status\", \"Render started\")\n    }\n\n    override fun onPdfRenderSuccess() {\n      Log.i(\"PDF Status\", \"Render successful\")\n      binding.pdfView.jumpToPage($number)  // Recommend to use `jumpToPage` inside `onPdfRenderSuccess`\n    }\n}\n```\n\n#### Page-level Navigation\nUse `jumpToPage(pageNumber)` to go directly to a specific page (0-based index). For floating \"Next\"/\"Previous\" buttons — especially in landscape mode where a page can be taller than the screen — prefer the smart scroll helpers that scroll within the current page first and only advance to the next page once the bottom (or top) of the current page is reached:\n\n```kotlin\n// Scroll down within the current page; go to next page when at the bottom.\nnextButton.setOnClickListener { binding.pdfView.scrollToNextPage() }\n\n// Scroll up within the current page; go to previous page when at the top.\nprevButton.setOnClickListener { binding.pdfView.scrollToPreviousPage() }\n```\n\n#### Zoom Change Listener\nYou can also monitor when the user zooms in or out using `zoomListener`:\n\n```kotlin\nbinding.pdfView.zoomListener = object : PdfRendererView.ZoomListener {\n    override fun onZoomChanged(isZoomedIn: Boolean, scale: Float) {\n        Log.i(\"PDF Zoom\", \"Zoomed in: $isZoomedIn, Scale: $scale\")\n    }\n}\n```\n\n### Ui Customizations\nYou need to add the custom theme to styles.xml/themes.xml file and override the required attribute values.\nParent theme can be either **Theme.PdfView.Light** or **Theme.PdfView.Dark** or the one with no actionbar from the application.\nNote: If parent is not one of the themes from this library, all of the pdfView attributes should be added to that theme.\n\n    \u003cstyle name=\"Theme.PdfView.SelectedTheme\" parent=\"@style/Theme.PdfView.Light\"\u003e\n        \u003citem name=\"pdfView_backIcon\"\u003e@drawable/ic_arrow_back\u003c/item\u003e\n        \u003citem name=\"pdfView_showToolbar\"\u003etrue\u003c/item\u003e\n        \u003citem name=\"pdfView_disableScreenshots\"\u003etrue\u003c/item\u003e\n        ...\n    \u003c/style\u003e\n\n\n#### Ui Customizations - Page number\n\nYou need to add the custom layout to pdf_view_page_no.xml file and override the required attribute\nvalues.\n\n    \u003c?xml version=\"1.0\" encoding=\"utf-8\"?\u003e  \n    \u003cTextView xmlns:android=\"http://schemas.android.com/apk/res/android\"  \n      android:id=\"@+id/pageNo\"  \n      android:layout_width=\"wrap_content\"  \n      android:layout_height=\"wrap_content\"  \n      android:layout_margin=\"18dp\"  \n      android:background=\"#9C27B0\"  \n      android:paddingStart=\"12dp\"  \n      android:paddingTop=\"4dp\"  \n      android:paddingEnd=\"12dp\"  \n      android:paddingBottom=\"4dp\"  \n      android:textColor=\"#ffffff\"  \n      android:textSize=\"16sp\"  \n      android:visibility=\"gone\" /\u003e\n\n\n\n#### Ui Page number\n\nYou need to add the custom string to strings.xml file and override the required strings.xml values.\n\nDefault:\n\n    \u003cstring name=\"pdfView_page_no\"\u003e%1$s of %2$s\u003c/string\u003e\n\nCustom:\n\n    \u003cstring name=\"pdfView_page_no\" \u003e%1$s / %2$s\u003c/string\u003e\n\n#### Supported attributes\n\n| Attribute Name | Type | Expected changes |\n|--|--|--|\n|pdfView_backIcon|drawable|Navigation icon|\n|pdfView_downloadIcon|drawable|Download icon|\n|pdfView_downloadIconTint|color|Download icon tint|\n|pdfView_toolbarColor|color|Actionbar background color|\n|pdfView_titleTextStyle|style|Actionbar title text appearance|\n|pdfView_progressBar|style|Progress bar style|\n\n## Who's using Pdf-Viewer?\n**👉 [Check out who's using Pdf-Viewer](/usecases.md)**\n\n## Contributing\n\nAny contributions you make are **greatly appreciated**.\n\n1. Fork the Project\n2. Create your Feature Branch (`git checkout -b feature/NewFeature`)\n3. Commit your Changes (`git commit -m 'Add some NewFeature'`)\n4. Push to the Branch (`git push origin feature/NewFeature`)\n5. Open a Pull Request\n\n## Donations\nIf this library helps you save time during development, you can buy me a cup of coffee :)\n\n[![paypal](https://www.paypalobjects.com/en_US/i/btn/btn_donateCC_LG.gif)](https://www.paypal.com/paypalme/afreakyelf)\n\n## Author\nMaintained by [Rajat Mittal](https://www.github.com/afreakyelf)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fafreakyelf%2Fpdf-viewer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fafreakyelf%2Fpdf-viewer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fafreakyelf%2Fpdf-viewer/lists"}