Custom Layout Example
Use some custom layout resources to alter the activity appearance.
/* * Copyright © 2020-2026 PSPDFKit GmbH. All rights reserved. * * The PSPDFKit Sample applications are licensed with a modified BSD license. * Please see License for details. This notice may not be removed from this file. */
package com.pspdfkit.catalog.examples.kotlin
import android.content.Contextimport android.net.Uriimport android.os.Bundleimport android.view.MenuItemimport android.view.Viewimport androidx.annotation.UiThreadimport androidx.core.view.GravityCompatimport androidx.drawerlayout.widget.DrawerLayoutimport androidx.drawerlayout.widget.DrawerLayout.SimpleDrawerListenerimport com.pspdfkit.catalog.Rimport com.pspdfkit.catalog.SdkExampleimport com.pspdfkit.catalog.tasks.ExtractAssetTaskimport com.pspdfkit.catalog.utils.Utilsimport com.pspdfkit.configuration.activity.PdfActivityConfigurationimport com.pspdfkit.configuration.activity.TabBarHidingModeimport com.pspdfkit.configuration.activity.ThumbnailBarModeimport com.pspdfkit.configuration.search.SearchTypeimport com.pspdfkit.document.PdfDocumentimport com.pspdfkit.listeners.OnVisibilityChangedListenerimport com.pspdfkit.ui.PdfActivityimport com.pspdfkit.ui.PdfActivityIntentBuilderimport com.pspdfkit.ui.PdfThumbnailGrid
/** * This example shows how to use a custom [PdfActivity] with a custom layout. In detail: * * - It subclasses the [PdfActivity] and uses a custom layout resource. * - It removes the thumbnail bar and adds two navigation buttons to the layouts ("Next" and "Previous"). * - It puts the thumbnail grid into the right navigation drawer. */class CustomLayoutExample(context: Context) : SdkExample(context, R.string.customLayoutExampleTitle, R.string.customLayoutExampleDescription) { override fun launchExample(context: Context, configuration: PdfActivityConfiguration.Builder) { // Define the custom layout of our activity inside the configuration. configuration.layout(R.layout.custom_pdf_activity)
// The custom layout is missing some UI elements, in order to prevent the activity from // accessing them we have to deactivate them in the configuration. configuration.apply { // The custom layout has no thumbnail bar. setThumbnailBarMode(ThumbnailBarMode.THUMBNAIL_BAR_MODE_NONE) // The custom layout has no document editor. documentEditorEnabled(false) // The custom layout has no document title overlay. documentTitleOverlayEnabled(false) // The custom layout has no navigation buttons. navigationButtonsEnabled(false) // This example shows the thumbnail grid in a custom drawer layout. thumbnailGridEnabled(true) // Disable forms editing. formEditingEnabled(false) // The custom layout has no content editor. contentEditingEnabled(false) // Disable measurements setMeasurementToolsEnabled(false) }
// Hide tab bar as it's not used by the custom layout. configuration.setTabBarHidingMode(TabBarHidingMode.HIDE)
// We keep things simple, and use inline search for this example. configuration.apply { setSearchType(SearchType.INLINE) }
// We use a custom utility class to extract the example document from the assets. ExtractAssetTask.extract(WELCOME_DOC, title, context) { documentFile -> // To start the `CustomLayoutActivity` create a launch intent using the builder. val intent = PdfActivityIntentBuilder.fromUri(context, Uri.fromFile(documentFile)) .configuration(configuration.build()) .activityClass(CustomLayoutActivity::class) .build() context.startActivity(intent) } }}
class CustomLayoutActivity : PdfActivity() {
/** * Total number of pages in the current document. */ private var documentPageCount = 0
private lateinit var drawerLayout: DrawerLayout private lateinit var thumbnailGridView: PdfThumbnailGrid
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState)
// Get all required views for customization. drawerLayout = findViewById(R.id.drawerLayout)
// Dynamically set the correct width of the thumbnail grid drawer. val thumbnailGridDrawer = findViewById<View>(R.id.thumbnailGridDrawer) Utils.setProperNavigationDrawerWidth(thumbnailGridDrawer)
thumbnailGridView = findViewById(R.id.pspdf__activity_thumbnail_grid)
// Register the thumbnail grid with the fragment, so it is notified of page changes. requirePdfFragment().addDocumentListener(thumbnailGridView)
// Toggle drawer when thumbnail grid visibility changes. thumbnailGridView.addOnVisibilityChangedListener(object : OnVisibilityChangedListener { override fun onShow(view: View) { drawerLayout.openDrawer(DRAWER_GRAVITY) }
override fun onHide(view: View) { drawerLayout.closeDrawer(DRAWER_GRAVITY) } })
// Ensure action bar and grid are visible when drawer is opened. drawerLayout.addDrawerListener(object : SimpleDrawerListener() { override fun onDrawerSlide(drawerView: View, slideOffset: Float) {}
override fun onDrawerClosed(drawerView: View) { thumbnailGridView.hide() }
override fun onDrawerStateChanged(newState: Int) { if (newState == DrawerLayout.STATE_DRAGGING) { thumbnailGridView.show() } } })
// Go to the tapped page, and close the thumbnail drawer after selecting a page. thumbnailGridView.setOnPageClickListener { _, pageIndex -> setPageIndex(pageIndex) toggleThumbnailGrid() }
// Flip to the next page when clicking on the next page button. findViewById<View>(R.id.nextPageButton).setOnClickListener { val currentPage = pageIndex if (currentPage < documentPageCount - 1) pageIndex = currentPage + 1 } // Flip to the previous page when clicking on the previous page button. findViewById<View>(R.id.previousPageButton).setOnClickListener { val currentPage = pageIndex if (currentPage > 0) pageIndex = currentPage - 1 } }
override fun onOptionsItemSelected(item: MenuItem): Boolean { when (item.itemId) { MENU_OPTION_THUMBNAIL_GRID -> { toggleThumbnailGrid() hidePSPDFViews()
// Consume the event, preventing the default behavior. return true } MENU_OPTION_OUTLINE, MENU_OPTION_SEARCH -> { hideThumbnailGrid() // Don't consume the event here since we want to fallback to default action handling. } } return super.onOptionsItemSelected(item) }
@Deprecated("Deprecated in Java") override fun onBackPressed() { super.onBackPressed() hideThumbnailGrid() }
/** * Called as soon as the PDF document has been loaded. */ @UiThread override fun onDocumentLoaded(document: PdfDocument) { super.onDocumentLoaded(document)
// Retrieve the total number of pages in the document. documentPageCount = document.pageCount }
private fun hidePSPDFViews() { pspdfKitViews.outlineView?.hide() pspdfKitViews.searchView?.hide() }
private fun hideThumbnailGrid() { if (drawerLayout.isDrawerVisible(DRAWER_GRAVITY)) { drawerLayout.closeDrawer(DRAWER_GRAVITY) } }
private fun toggleThumbnailGrid() { if (drawerLayout.isDrawerOpen(DRAWER_GRAVITY)) { thumbnailGridView.hide() drawerLayout.closeDrawer(DRAWER_GRAVITY) } else { thumbnailGridView.show() drawerLayout.openDrawer(DRAWER_GRAVITY) } }
companion object { /** Gravity of the thumbnail grid drawer. */ private const val DRAWER_GRAVITY = GravityCompat.END }}This code sample is an example that illustrates how to use our SDK. Please adapt it to your specific use case.