---
title: "Multiple Documents (Compose Pager)"
canonical_url: "https://www.nutrient.io/guides/android/samples/multiple-documents-compose-pager-kotlin/"
md_url: "https://www.nutrient.io/guides/android/samples/multiple-documents-compose-pager-kotlin.md"
last_updated: "2025-07-02T00:00:00.000Z"
description: "Swipe between multiple PDFs with a Compose HorizontalPager."
---

# Multiple Documents (Compose Pager)

Swipe between multiple PDFs with a Compose HorizontalPager.

[Get Started](https://www.nutrient.io/sdk/android/getting-started.md)

[All Samples](https://www.nutrient.io/guides/android/samples.md)

[Download](https://www.nutrient.io/guides/android/downloads.md)

[Launch Demo](https://www.nutrient.io/demo/)

---

```kotlin

/*
 *   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.Context
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.widget.Toast
import androidx.activity.compose.BackHandler
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.appcompat.app.AppCompatActivity
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.expandVertically
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.animation.shrinkVertically
import androidx.compose.animation.slideInVertically
import androidx.compose.animation.slideOutVertically
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.captionBar
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.ime
import androidx.compose.foundation.layout.imePadding
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.statusBarsPadding
import androidx.compose.foundation.pager.HorizontalPager
import androidx.compose.foundation.pager.rememberPagerState
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.PrimaryTabRow
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Tab
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.SideEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.key
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.unit.Density
import androidx.compose.ui.unit.dp
import androidx.core.net.toUri
import com.pspdfkit.catalog.R
import com.pspdfkit.catalog.SdkExample
import com.pspdfkit.catalog.SdkExample.Companion.WELCOME_DOC
import com.pspdfkit.catalog.ui.theming.CatalogTheme
import com.pspdfkit.compose.theme.MainToolbarColors
import com.pspdfkit.compose.theme.ToolbarPopupColors
import com.pspdfkit.compose.theme.getUiColors
import com.pspdfkit.configuration.activity.PdfActivityConfiguration
import com.pspdfkit.configuration.page.PageFitMode
import com.pspdfkit.configuration.page.PageLayoutMode
import com.pspdfkit.configuration.page.PageScrollDirection
import com.pspdfkit.configuration.page.PageScrollMode
import com.pspdfkit.jetpack.compose.components.MainToolbar
import com.pspdfkit.jetpack.compose.interactors.DefaultListeners
import com.pspdfkit.jetpack.compose.interactors.DocumentState
import com.pspdfkit.jetpack.compose.interactors.getDefaultDocumentManager
import com.pspdfkit.jetpack.compose.interactors.rememberDocumentState
import com.pspdfkit.jetpack.compose.views.DocumentView
import com.pspdfkit.ui.toolbar.ContextualToolbar
import com.pspdfkit.ui.toolbar.ToolbarCoordinatorLayout
import kotlinx.coroutines.launch
import java.io.File
import java.lang.ref.WeakReference

/**
 * List of PDF files to be displayed in the example
 */
private val FILES =
    listOf(
        WELCOME_DOC.removeSuffix(".pdf"),
        "Scientific-paper",
        "The-Cosmic-Context-for-Life",
    )

/**
 * Example entry point showing how to display multiple PDF documents with individual configurations
 */
class DocumentPagerExample(context: Context) :
    SdkExample(context, R.string.documentPagerExampleTitle, R.string.documentPagerExampleDescription) {
    override fun launchExample(context: Context, configuration: PdfActivityConfiguration.Builder) {
        // Extract the documents from assets before launching the activity
        FileUtils.copyFilesFromAssetsToLocalStorage(context, FILES) {
            val intent = Intent(context, DocumentPagerExampleActivity::class.java)
            context.startActivity(intent)
        }
    }
}

/**
 * Activity hosting the multiple PDF viewer Composable
 */
class DocumentPagerExampleActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        enableEdgeToEdge()
        super.onCreate(savedInstanceState)

        setContent {
            CatalogTheme {
                PdfViewerPager(
                    files = FILES,
                    getFileUri = { filename ->
                        File(filesDir, "$filename.pdf").toUri()
                    },
                )
            }
        }
    }
}

/**
 * Manages DocumentState instances for multiple PDFs using WeakReferences to prevent memory leaks
 */
class DocumentStateManager(private val files: List<String>, private val getFileUri: (String) -> Uri) {
    private val documentStates = mutableMapOf<Int, WeakReference<DocumentState>>()

    /**
     * Returns an existing DocumentState or creates a new one if needed
     *
     * @param index The index of the PDF in the files list
     * @return A DocumentState for the PDF at the given index
     */
    @Composable
    fun getOrCreateDocumentState(index: Int): DocumentState {
        val weakRef = documentStates[index]
        val existingState = weakRef?.get()

        // Return existing state if available
        if (existingState!= null) {
            return existingState
        }

        // Create a new state with different configuration based on document index
        val context = LocalContext.current
        val commonConfig =
            PdfActivityConfiguration.Builder(context).defaultToolbarEnabled(false).fitMode(PageFitMode.FIT_TO_WIDTH)
        val uri = getFileUri(files[index])
        val configuration = createConfigurationForIndex(index, commonConfig)
        val newState = rememberDocumentState(uri, configuration)

        // Store weak reference and return the new state
        documentStates[index] = WeakReference(newState)
        return newState
    }

    /**
     * Creates a specific configuration based on the document index
     */
    private fun createConfigurationForIndex(index: Int, commonConfig: PdfActivityConfiguration.Builder) = when (index) {
        0 -> commonConfig.scrollMode(PageScrollMode.PER_PAGE).build()
        1 -> commonConfig.scrollDirection(PageScrollDirection.VERTICAL).build()
        else -> commonConfig.layoutMode(PageLayoutMode.DOUBLE).build()
    }
}

/**
 * Main Composable that displays multiple PDFs with tabs for navigation
 *
 * @param files List of PDF filenames to display
 * @param getFileUri Function to convert a filename to a URI
 */
@Composable
fun PdfViewerPager(files: List<String>, getFileUri: (String) -> Uri) {
    val localDensity = LocalDensity.current
    val documentStateManager =
        remember(files) {
            DocumentStateManager(files, getFileUri)
        }

    val pagerState = rememberPagerState(pageCount = { files.size })
    val coroutineScope = rememberCoroutineScope()
    var hideTopBar by remember { mutableStateOf(true) }

    Column(modifier = Modifier.fillMaxSize()) {
        Scaffold(
            topBar = {
                AnimatedVisibility(
                    visible = hideTopBar,
                    enter =
                    slideInVertically { with(localDensity) { -40.dp.roundToPx() } } +
                        expandVertically(expandFrom = Alignment.Top) +
                        fadeIn(initialAlpha = 0.3f),
                    exit = slideOutVertically() + shrinkVertically() + fadeOut(),
                ) {
                    // Tab row for document selection
                    PdfTabRow(
                        files = files,
                        currentPage = pagerState.currentPage,
                        onTabSelected = { index ->
                            coroutineScope.launch {
                                pagerState.animateScrollToPage(index)
                            }
                        },
                    )
                }
            },
        ) { paddingValues ->
            // Horizontal pager for PDF documents
            HorizontalPager(
                userScrollEnabled = false,
                state = pagerState,
                modifier = Modifier.weight(1f),
            ) { page ->
                key(page) {
                    PdfDocumentPage(
                        page = page,
                        documentStateManager = documentStateManager,
                        paddingValues = paddingValues,
                        localDensity = localDensity,
                    ) {
                        hideTopBar = it
                    }
                }
            }
        }
    }
}

/**
 * Composable for the tab row to switch between documents
 */
@OptIn(ExperimentalMaterial3Api::class)
@Composable
private fun PdfTabRow(files: List<String>, currentPage: Int, onTabSelected: (Int) -> Unit) {
    PrimaryTabRow(
        selectedTabIndex = currentPage,
        modifier =
        Modifier.fillMaxWidth().background(MaterialTheme.colorScheme.background).statusBarsPadding(),
    ) {
        files.forEachIndexed { index, title ->
            Tab(
                selected = currentPage == index,
                onClick = { onTabSelected(index) },
                text = {
                    Column(
                        Modifier.padding(4.dp).fillMaxWidth(),
                        verticalArrangement = Arrangement.SpaceBetween,
                    ) {
                        Text(
                            text = title,
                            style = MaterialTheme.typography.bodyLarge,
                            modifier = Modifier.align(Alignment.CenterHorizontally),
                        )
                    }
                },
            )
        }
    }
}

/**
 * Composable for an individual PDF document page
 */
@Composable
private fun PdfDocumentPage(
    page: Int,
    documentStateManager: DocumentStateManager,
    paddingValues: PaddingValues,
    localDensity: Density,
    updateTopBarVisibility: (Boolean) -> Unit,
) {
    val context = LocalContext.current
    val documentState = documentStateManager.getOrCreateDocumentState(page)

    var immersiveModeEnabled by remember { mutableStateOf(false) }
    var contextualToolbarShown by remember { mutableStateOf(false) }
    val searchViewShown by documentState.searchViewShown.collectAsState()
    val toolbarVisibility =!immersiveModeEnabled &&!contextualToolbarShown &&!searchViewShown
    val tabRowVisibility =!immersiveModeEnabled &&!searchViewShown

    LaunchedEffect(documentState) {
        documentState.setOnContextualToolbarLifecycleListener(object : ToolbarCoordinatorLayout.OnContextualToolbarLifecycleListener {
            override fun onPrepareContextualToolbar(toolbar: ContextualToolbar<*>) = Unit
            override fun onDisplayContextualToolbar(toolbar: ContextualToolbar<*>) {
                contextualToolbarShown = true
            }
            override fun onRemoveContextualToolbar(toolbar: ContextualToolbar<*>) {
                contextualToolbarShown = false
                immersiveModeEnabled = false
            }
        })
    }

    LaunchedEffect(searchViewShown) {
        if (!searchViewShown) immersiveModeEnabled = false
    }

    LaunchedEffect(tabRowVisibility) {
        updateTopBarVisibility(tabRowVisibility)
    }

    val enableViewSpacer by documentState.viewWithOverlappingToolbarShown.collectAsState()

    // Manage the content view's top padding (which offsets the thumbnail grid below the visible
    // toolbar) entirely from Compose via SideEffect. This runs synchronously after every
    // recomposition and calls into the SDK's setContentViewTopPadding, which suppresses the
    // automatic Java-side adjustments in ToolbarCoordinatorLayout so the two don't race.
    //
    // Crucially, enableViewSpacer is true both during normal grid mode AND editing mode, so the
    // padding value stays constant across that transition — no grid jump, no thumbnail recycling.
    //
    // We use the SDK's own contextual toolbar height (toolbarSizePx) rather than deriving it from
    // the Compose MainToolbar's measured height. The measured height can be stale by one frame
    // when showTitleBar changes (e.g. as the grid opens), which would cause a 1-frame spike that
    // pushes the grid too low. The SDK value is always correct and matches adjustContentViewTopPadding.
    val contextualToolbarSizePx = documentState.getContextualToolbarSizePx()
    SideEffect {
        documentState.setContentViewTopPadding(if (enableViewSpacer) contextualToolbarSizePx else 0)
    }

    val imeVisible = WindowInsets.ime.getBottom(LocalDensity.current) > 0
    BackHandler(enabled = (contextualToolbarShown || enableViewSpacer) &&!imeVisible) {
        documentState.handleBackPress()
    }

    Box(
        contentAlignment = Alignment.TopCenter,
    ) {
        Column(modifier = Modifier.padding(top = paddingValues.calculateTopPadding())) {
            // PDF Document View
            DocumentView(
                documentState = documentState,
                modifier = Modifier.weight(1f).imePadding(),
                documentManager =
                createDocumentManager(context) {
                    immersiveModeEnabled = it
                },
            )
        }

        // Animated toolbar. When the contextual (editing) toolbar is taking over, skip the slide
        // and shrink — a plain fade avoids visual noise while the editing toolbar slides in.
        AnimatedVisibility(
            visible = toolbarVisibility,
            enter =
            slideInVertically { with(localDensity) { -40.dp.roundToPx() } } +
                expandVertically(expandFrom = Alignment.Top) +
                fadeIn(initialAlpha = 0.3f),
            exit = if (contextualToolbarShown) fadeOut() else slideOutVertically() + shrinkVertically() + fadeOut(),
        ) {
            // Common toolbar for all pages
            MainToolbar(
                modifier = Modifier.padding(top = paddingValues.calculateTopPadding()),
                documentState = documentState,
                windowInsets = WindowInsets.captionBar,
                colorScheme = createCustomUiColors(),
                showTitleBar =!enableViewSpacer,
            )
        }
    }
}

/**
 * Creates a document manager with listeners for document events
 */
@Composable
private fun createDocumentManager(context: Context, onImmersiveModeChanged: (Boolean) -> Unit) = getDefaultDocumentManager(
    documentListener =
    DefaultListeners.documentListeners(
        onDocumentLoaded = {
            Toast.makeText(context, "Document loaded", Toast.LENGTH_SHORT).show()
        },
    ),
    annotationListener =
    DefaultListeners.annotationListeners(
        onAnnotationSelected = { annotation, _ ->
            Toast.makeText(
                    context,
                    "${annotation.type} selected",
                    Toast.LENGTH_SHORT,
                ).show()
        },
        onAnnotationDeselected = { annotation, _ ->
            Toast.makeText(
                    context,
                    "${annotation.type} deselected",
                    Toast.LENGTH_SHORT,
                ).show()
        },
    ),
    uiListener =
    DefaultListeners.uiListeners(
        onImmersiveModeEnabled = onImmersiveModeChanged,
    ),
)

/**
 * Creates custom UI colors for the toolbar
 */
@Composable
private fun createCustomUiColors() = getUiColors().copy(
    mainToolbar =
    MainToolbarColors(
        backgroundColor = MaterialTheme.colorScheme.primary,
        textColor = MaterialTheme.colorScheme.onPrimary,
        popup = ToolbarPopupColors(backgroundColor = MaterialTheme.colorScheme.primary),
        titleTextColor = MaterialTheme.colorScheme.onPrimary,
    ),
)

/**
 * Utility object for file operations
 */
object FileUtils {
    /**
     * Copies files from assets to local storage
     *
     * @param context Android context
     * @param fileNames List of filenames to copy
     * @param onComplete Callback to run after copying completes
     */
    fun copyFilesFromAssetsToLocalStorage(context: Context, fileNames: List<String>, onComplete: () -> Unit = {}) {
        fileNames.forEach { fileName ->
            val destinationFile = File(context.filesDir, "$fileName.pdf")

            if (!destinationFile.exists()) {
                try {
                    context.assets.open("$fileName.pdf").use { inputStream ->
                        destinationFile.outputStream().use { outputStream ->
                            inputStream.copyTo(outputStream, BUFFER_SIZE)
                        }
                    }
                } catch (e: Exception) {
                    e.printStackTrace()
                }
            }
        }

        onComplete()
    }

    private const val BUFFER_SIZE = 8192
}

```

This code sample is an example that illustrates how to use our SDK. Please adapt it to your specific use case.

---

## Related pages

- [Application Policy](/guides/android/samples/application-policy-kotlin.md)
- [Compose Image Document](/guides/android/samples/compose-image-document-kotlin.md)
- [Custom Form Highlight Color](/guides/android/samples/custom-form-highlight-color-java.md)
- [Custom Page Templates](/guides/android/samples/custom-page-templates-java.md)
- [Digital Signature (Basic)](/guides/android/samples/digital-signature-basic-kotlin.md)
- [Disabled Annotation Property](/guides/android/samples/disabled-annotation-property-java.md)
- [Image Document](/guides/android/samples/image-document-kotlin.md)
- [Inline Multimedia](/guides/android/samples/inline-multimedia-kotlin.md)
- [JavaScript Form Filling](/guides/android/samples/javascript-form-filling-kotlin.md)
- [JavaScript Calculator](/guides/android/samples/javascript-calculator-kotlin.md)
- [Merge Documents](/guides/android/samples/merge-documents-kotlin.md)
- [Overlay Visibility](/guides/android/samples/overlay-visibility-kotlin.md)
- [Password Protected PDF](/guides/android/samples/password-protected-pdf-kotlin.md)
- [PdfFragment](/guides/android/samples/pdffragment-kotlin.md)
- [Playground](/guides/android/samples/playground-kotlin.md)
- [Reader View](/guides/android/samples/reader-view-kotlin.md)
- [Scientific Paper](/guides/android/samples/scientific-paper-kotlin.md)
- [Selection Customization](/guides/android/samples/selection-customization-java.md)
- [Signature Storage Database](/guides/android/samples/signature-storage-database-kotlin.md)
- [Text Field Suggestions](/guides/android/samples/text-field-suggestions-kotlin.md)
- [Try Instant](/guides/android/samples/try-instant-kotlin.md)
- [Annotation Rendering](/guides/android/samples/annotation-rendering-kotlin.md)
- [Compose Navigation](/guides/android/samples/compose-navigation-kotlin.md)
- [Custom Download Dialog](/guides/android/samples/custom-download-dialog-java.md)
- [Custom Sharing Dialog](/guides/android/samples/custom-sharing-dialog-java.md)
- [Custom ActionBar Actions](/guides/android/samples/custom-actionbar-actions-kotlin.md)
- [Digital Signature (Third-Party)](/guides/android/samples/digital-signature-third-party-kotlin.md)
- [AI Assistant (Multiple Documents, ViewPager)](/guides/android/samples/ai-assistant-multiple-documents-viewpager-kotlin.md)
- [Custom Data Provider](/guides/android/samples/custom-data-provider-kotlin.md)
- [Custom Main Toolbar](/guides/android/samples/custom-main-toolbar-kotlin.md)
- [Custom Note Hinter](/guides/android/samples/custom-note-hinter-kotlin.md)
- [Custom Activity Toolbars](/guides/android/samples/custom-activity-toolbars-java.md)
- [Annotations with Transparency](/guides/android/samples/annotations-with-transparency-kotlin.md)
- [Custom Outline Provider](/guides/android/samples/custom-outline-provider-kotlin.md)
- [Custom Layout](/guides/android/samples/custom-layout-kotlin.md)
- [Custom Stamp Annotations](/guides/android/samples/custom-stamp-annotations-java.md)
- [Custom Toolbar Grouping](/guides/android/samples/custom-toolbar-grouping-java.md)
- [Custom Sharing Menu](/guides/android/samples/custom-sharing-menu-java.md)
- [Digital Signature (Manual)](/guides/android/samples/digital-signature-manual-kotlin.md)
- [Digital Signature (Two-Step)](/guides/android/samples/digital-signature-two-step-kotlin.md)
- [Document Download](/guides/android/samples/document-download-kotlin.md)
- [Custom Activity Form Editing](/guides/android/samples/custom-activity-form-editing-java.md)
- [Custom Search UI (Compose)](/guides/android/samples/custom-search-ui-compose-kotlin.md)
- [Document from Canvas](/guides/android/samples/document-from-canvas-kotlin.md)
- [Document Sharing](/guides/android/samples/document-sharing-java.md)
- [Document Switcher](/guides/android/samples/document-switcher-java.md)
- [DocumentView Composable](/guides/android/samples/documentview-composable-kotlin.md)
- [Download Progress](/guides/android/samples/download-progress-kotlin.md)
- [Dynamic Pages on Scroll](/guides/android/samples/dynamic-pages-on-scroll-kotlin.md)
- [File Annotation Creation](/guides/android/samples/file-annotation-creation-kotlin.md)
- [Form Click Intercept (Compose)](/guides/android/samples/form-click-intercept-compose-kotlin.md)
- [Form Filling](/guides/android/samples/form-filling-kotlin.md)
- [Form Creation](/guides/android/samples/form-creation-kotlin.md)
- [Fragment Runtime Configuration](/guides/android/samples/fragment-runtime-configuration-kotlin.md)
- [Instant Document JSON](/guides/android/samples/instant-document-json-kotlin.md)
- [Instant JSON Attachment](/guides/android/samples/instant-json-attachment-kotlin.md)
- [Inline Search](/guides/android/samples/inline-search-java.md)
- [JavaScript Actions](/guides/android/samples/javascript-actions-kotlin.md)
- [LTV Signature](/guides/android/samples/ltv-signature-kotlin.md)
- [OCR](/guides/android/samples/ocr-kotlin.md)
- [HTML-to-PDF Conversion](/guides/android/samples/html-to-pdf-conversion-kotlin.md)
- [PDF from Image](/guides/android/samples/pdf-from-image-kotlin.md)
- [PdfUiFragment](/guides/android/samples/pdfuifragment-kotlin.md)
- [Popup Toolbar Customization](/guides/android/samples/popup-toolbar-customization-kotlin.md)
- [Programmatic Zoom](/guides/android/samples/programmatic-zoom-kotlin.md)
- [Remote URL](/guides/android/samples/remote-url-kotlin.md)
- [Runtime Configuration](/guides/android/samples/runtime-configuration-kotlin.md)
- [Signature Parcelize](/guides/android/samples/signature-parcelize-kotlin.md)
- [Sound Extraction](/guides/android/samples/sound-extraction-kotlin.md)
- [Split View](/guides/android/samples/split-view-java.md)
- [Tabbed Documents](/guides/android/samples/tabbed-documents-kotlin.md)
- [Thumbnail Bar Modes](/guides/android/samples/thumbnail-bar-modes-kotlin.md)
- [Vertical Scrollbar](/guides/android/samples/vertical-scrollbar-java.md)
- [Watermarks](/guides/android/samples/watermarks-kotlin.md)
- [UI View Modes](/guides/android/samples/ui-view-modes-kotlin.md)
- [XFDF Import/Export](/guides/android/samples/xfdf-import-export-kotlin.md)
- [Annotation Selection Styling](/guides/android/samples/annotation-selection-styling-kotlin.md)
- [Annotation Configuration](/guides/android/samples/annotation-configuration-kotlin.md)
- [Annotation Flags](/guides/android/samples/annotation-flags-kotlin.md)
- [Annotation Overlay](/guides/android/samples/annotation-overlay-java.md)
- [Add LTV to Existing Signature](/guides/android/samples/add-ltv-to-existing-signature-kotlin.md)
- [Annotation Sidebar](/guides/android/samples/annotation-sidebar-kotlin.md)
- [Custom Annotation Inspector](/guides/android/samples/custom-annotation-inspector-java.md)
- [Custom Electronic Signature](/guides/android/samples/custom-electronic-signature-java.md)
- [Document Processing](/guides/android/samples/document-processing-kotlin.md)
- [Custom Annotation Creation Toolbar](/guides/android/samples/custom-annotation-creation-toolbar-java.md)
- [Bookmark Highlighting](/guides/android/samples/bookmark-highlighting-kotlin.md)
- [Document Comparison](/guides/android/samples/document-comparison-kotlin.md)
- [E-Learning](/guides/android/samples/e-learning-kotlin.md)
- [External Document](/guides/android/samples/external-document-kotlin.md)
- [Electronic + Digital Signing](/guides/android/samples/electronic-digital-signing-kotlin.md)
- [Forms with JavaScript](/guides/android/samples/forms-with-javascript-kotlin.md)
- [Generate PDF Report](/guides/android/samples/generate-pdf-report-kotlin.md)
- [Kiosk Grid](/guides/android/samples/kiosk-grid-kotlin.md)
- [Multimedia Annotations](/guides/android/samples/multimedia-annotations-kotlin.md)
- [Overlay Views](/guides/android/samples/overlay-views-kotlin.md)
- [Measurement Tools](/guides/android/samples/measurement-tools-kotlin.md)
- [Search Indexing](/guides/android/samples/search-indexing-kotlin.md)
- [AI Assistant (Single Document)](/guides/android/samples/ai-assistant-single-document-kotlin.md)
- [AI Assistant (Multiple Documents, Compose)](/guides/android/samples/ai-assistant-multiple-documents-compose-kotlin.md)
- [Filterable Thumbnail Grid](/guides/android/samples/filterable-thumbnail-grid-kotlin.md)
- [Tabbed Documents (Persistent)](/guides/android/samples/tabbed-documents-persistent-kotlin.md)
- [Annotation Creation](/guides/android/samples/annotation-creation-kotlin.md)
- [Construction Floor Plan](/guides/android/samples/construction-floor-plan-kotlin.md)
- [Hide and Reveal Areas](/guides/android/samples/hide-and-reveal-areas-kotlin.md)
- [AES Encrypted File](/guides/android/samples/aes-encrypted-file-java.md)
- [Custom Search UI (Views)](/guides/android/samples/custom-search-ui-views-java.md)
- [Screen Reader](/guides/android/samples/screen-reader-java.md)

