Jetpack Compose Pager change currentPage

896 Views Asked by At

Is there a manual way or an appropriate way to change the current page for a Pager?

I may be breaking some written rules, but essentially I am updating the content of pages, but not changing the number of pages.

The original list might be

A
B
C
D
… (repeat ABCD forever until you cap at Int.MAX_VALUE)

And the next minute it might be

A
B
C
D
E
F
… (same repeat)

I have accurately figured out how to calculate where I want to be in each pager if the number of values changes for any reason, but nothing I’ve done changes the value.

    val pageCount = Int.MAX_VALUE
    val halfSet = (pageCount / 2)
    val offset = halfSet % items.size
    val initial = halfSet - offset
    val initialPage = initial + selected - (initial % items.size) - 1 // This changes
    val pageState = rememberPagerState(
        initialPage = initialPage // This never updates
    )

    LaunchedEffect(
        key1 = pageState,
        key2 = initialPage // this is also constant
    ) {
        snapshotFlow { pageState.currentPage }.collect { page ->
            // Center page is a little strange... So. +1...
            // This definitely breaks or gets weird near the edges.
            //val actualPage = (if(intitalPage != page) intitalPage else page) + 1 // forever returns the first value that intialPage equaled
            val actualPage = page + 1 
            actualSelected = actualPage % items.size
            onChange(actualSelected)
            Log.d(TAG, "$actualPage ${items[actualSelected]} ")
        }
    }

The actualSelected technically is correct now because it does return the value that the page is currently on. I’ve stumbled into that working out. But if A was the selected value and the size of the list changes D might become selected and I really want A to stay. The initalPage is correctly returning to me the position I want it to be, but nothing I’m doing fixes it. And technically scrolling to it causes a ton of recompositions I don’t want. I just want it to “jump” or be at the right page I tell it to be.

1

There are 1 best solutions below

0
Cayce K On

Figured it out…

    val pageCount = Int.MAX_VALUE
    val halfSet = (pageCount / 2)
    val offset = halfSet % items.size
    val initial = halfSet - offset
    val target = initial + selected - (initial % items.size) - 1
    val pageState = rememberPagerState(
        initialPage = target
    )

    LaunchedEffect(
        key1 = items
    ) {
        pageState.scrollToPage(target)
    }

    LaunchedEffect(
        key1 = pageState,
        key2 = items
    ) {
        snapshotFlow { pageState.currentPage }.collect { page ->
            // Center page is a little strange... So. +1...
            // This definitely breaks or gets weird near the edges.
            val actualPage = page + 1
            actualSelected = actualPage % items.size
            onChange(actualSelected)
            if(debug) Log.d(TAG, "$actualPage ${items[actualSelected]} ")
        }
    }

So essentially you have to use 2 LaunchedEffect listeners. I don’t know exactly why as I tried to do the scrollToPage(Int) in the second one before and it didn’t work. If anyone has details on that that would be beneficial I think.

However, this works very well.