How to Handle Touch Scrolling a Compose DocumentView inside a Scrollable Compose Container

Say you have a DocumentView inside a Compose HorizontalPager and you want to be able to scroll the document vertically and scroll the pager horizontally. To do this, you need to tell the pager that the document is being scrolled and block the scroll on the pager.

PSPDFKit has an onDocumentScroll listener as part of the DocumentManager’s UiListener, which can be used to check if the document is being scrolled.

The code below shows our PDF user interface (UI) composable, which contains our DocumentView. This is where we pass the DocumentView our scrolling state lambda in which we can tell the parent pager whether or not we’re scrolling:

@Composable
fun PdfUI(pdf: File, scroll: (ScrollState) -> Unit = {}) {

    ... // Various scaffolding code, etc. See other examples for details.

    DocumentView(
        documentState,
        modifier = Modifier.padding(it),
        documentManager = getDefaultDocumentManager(
            // Implement the `onDocumentScroll` listener and call the passed lambda.
            uiListener = DefaultListeners.uiListeners(
                onDocumentScroll = {
                    scroll.invoke(it)
                }
            )
        )
    )
}

And here’s MainScreen, which contains HorizontalPager:

@Composable
fun MainScreen(navigateTo: (String) -> Unit) {

    ... // Various scaffolding code. etc. See other examples for details.

    Box() {
        val localPdfs = listOfLocalPdfFiles()
        val state = rememberPagerState(pageCount =  { 3 })
        if (state.isScrollInProgress) {
            pagerScroll = true
        }
        // Enable/disable pager scrolling using the `pagerScroll` flag.
        HorizontalPager(
            modifier = Modifier.fillMaxSize(),
            userScrollEnabled = pagerScroll,
            state = state
        ) { page ->
            when (page) {
                in 0 until 3 -> PdfUI(
                    pdf = File(localPdfs.first().path),
                ) { scroll ->
                    // Set the `pagerScroll` flag based on the scroll state of the `DocumentView`.
                    pagerScroll = scroll == ScrollState.IDLE
                }
            }
        )
        }
    }
}