GlimmerPagerState

class GlimmerPagerState : ScrollableState


The state that can be used to control GlimmerHorizontalPager.

Summary

Public companion properties

Saver<GlimmerPagerState, *>

The default Saver implementation for GlimmerPagerState.

Public constructors

@RememberInComposition
GlimmerPagerState(
    currentPage: @IntRange(from = 0) Int,
    currentPageOffsetFraction: @FloatRange(from = -0.5, to = 0.5) Float,
    pageCount: () -> Int
)

Public functions

suspend Unit
animateScrollToPage(page: Int, animationSpec: AnimationSpec<Float>)

Scroll to the given page with an animation.

open Float
Float

A utility function to help to calculate a given page's offset.

Unit
requestScrollToPage(
    page: @IntRange(from = 0) Int,
    pageOffsetFraction: @FloatRange(from = -0.5, to = 0.5) Float
)

Requests the page to be at the snapped position during the next remeasure, offset by pageOffsetFraction, and schedules a remeasure.

open suspend Unit
scroll(scrollPriority: MutatePriority, block: suspend ScrollScope.() -> Unit)
suspend Unit

Scroll immediately to the given page, without animating.

Unit
ScrollScope.updateCurrentPage(
    page: Int,
    pageOffsetFraction: @FloatRange(from = -0.5, to = 0.5) Float
)

Jump immediately to a given page with a given pageOffsetFraction inside a ScrollScope.

Unit

Used to update targetPage during a programmatic scroll operation.

Public properties

open Boolean

Whether this pager can scroll backward (is not at the first page).

open Boolean

Whether this pager can scroll forward (has more pages to show).

Int

The page that sits closest to the snapped position.

Float

Indicates how far the current page is to the snapped position, this will vary from -0.5 (page is offset towards the start of the layout) to 0.5 (page is offset towards the end of the layout).

InteractionSource

InteractionSource that will be used to dispatch drag events when this pager is being dragged.

open Boolean

Whether this pager is currently scrolling by gesture, fling or animation.

open Boolean

Whether the last scroll action was in the backward direction.

open Boolean

Whether the last scroll action was in the forward direction.

GlimmerPagerLayoutInfo

A GlimmerPagerLayoutInfo that contains information about the Pager's last layout pass.

Int

The total amount of pages present in this pager.

Int

The page that is currently "settled".

Int

The page that is currently being scrolled towards.

Public companion properties

Saver

Added in 1.0.0-alpha12
val SaverSaver<GlimmerPagerState, *>

The default Saver implementation for GlimmerPagerState.

Public constructors

GlimmerPagerState

Added in 1.0.0-alpha12
@RememberInComposition
GlimmerPagerState(
    currentPage: @IntRange(from = 0) Int = 0,
    currentPageOffsetFraction: @FloatRange(from = -0.5, to = 0.5) Float = 0.0f,
    pageCount: () -> Int
)
Parameters
currentPage: @IntRange(from = 0) Int = 0

The index of the page to show initially. Must be non-negative. Defaults to 0.

currentPageOffsetFraction: @FloatRange(from = -0.5, to = 0.5) Float = 0.0f

The offset of the initial page as a fraction of the page size. This should vary between -0.5 and 0.5 and indicates how to offset the initial page from the snapped position.

pageCount: () -> Int

A lambda returning the total number of pages in the pager.

Public functions

animateScrollToPage

Added in 1.0.0-alpha12
suspend fun animateScrollToPage(
    page: Int,
    animationSpec: AnimationSpec<Float> = spring()
): Unit

Scroll to the given page with an animation.

import androidx.compose.animation.core.animate
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Modifier
import androidx.xr.glimmer.Button
import androidx.xr.glimmer.Card
import androidx.xr.glimmer.Text
import androidx.xr.glimmer.pager.GlimmerHorizontalPager
import androidx.xr.glimmer.pager.GlimmerPagerState
import androidx.xr.glimmer.pager.rememberGlimmerPagerState

val state = rememberGlimmerPagerState(initialPage = 5, pageCount = { 10 })
val scope = rememberCoroutineScope()
Column {
    Button(onClick = { scope.launch { state.animateScrollToPage(1) } }) {
        Text(text = "Scroll to Page 1")
    }

    GlimmerHorizontalPager(modifier = Modifier.fillMaxSize(), state = state) { page ->
        Card { Text(text = "Page: $page") }
    }
}
Parameters
page: Int

the index of the page to scroll to.

animationSpec: AnimationSpec<Float> = spring()

the AnimationSpec to be used for the scroll animation.

dispatchRawDelta

Added in 1.0.0-alpha12
open fun dispatchRawDelta(delta: Float): Float

getOffsetDistanceInPages

Added in 1.0.0-alpha12
fun getOffsetDistanceInPages(page: Int): Float

A utility function to help to calculate a given page's offset. This is an offset that represents how far page is from the settled position (represented by currentPage offset). The difference here is that currentPageOffsetFraction is a value between -0.5 and 0.5 and the value calculated by this function can be larger than these numbers if page is different than currentPage.

For instance, if currentPage=0 and we call getOffsetDistanceInPages for page 3, the result will be 3, meaning the given page is 3 pages away from the current page (the sign represent the direction of the offset, positive is forward, negative is backwards). Another example is if currentPage=3 and we call getOffsetDistanceInPages for page 1, the result would be -2, meaning we're 2 pages away (moving backwards) to the current page.

This offset also works in conjunction with currentPageOffsetFraction, so if currentPage is out of its snapped position (i.e. currentPageOffsetFraction!=0) then the calculated value will still represent the offset in number of pages (in this case, not whole pages). For instance, if currentPage=1 and we're slightly offset, currentPageOffsetFraction=0.2, if we call this to page 2, the result would be 0.8, that is 0.8 page away from current page (moving forward).

Parameters
page: Int

The page to calculate the offset from. This should be between 0 and pageCount.

Returns
Float

The offset of page with respect to currentPage.

requestScrollToPage

Added in 1.0.0-alpha12
fun requestScrollToPage(
    page: @IntRange(from = 0) Int,
    pageOffsetFraction: @FloatRange(from = -0.5, to = 0.5) Float = 0.0f
): Unit

Requests the page to be at the snapped position during the next remeasure, offset by pageOffsetFraction, and schedules a remeasure.

The scroll position will be updated to the requested position rather than maintain the index based on the current page key (when a data set change will also be applied during the next remeasure), but only for the next remeasure.

Any scroll in progress will be cancelled.

Parameters
page: @IntRange(from = 0) Int

the index to which to scroll. Must be non-negative.

pageOffsetFraction: @FloatRange(from = -0.5, to = 0.5) Float = 0.0f

the offset fraction that the page should end up after the scroll.

scroll

Added in 1.0.0-alpha12
open suspend fun scroll(scrollPriority: MutatePriority, block: suspend ScrollScope.() -> Unit): Unit

scrollToPage

Added in 1.0.0-alpha12
suspend fun scrollToPage(page: Int): Unit

Scroll immediately to the given page, without animating.

import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Modifier
import androidx.xr.glimmer.Button
import androidx.xr.glimmer.Card
import androidx.xr.glimmer.Text
import androidx.xr.glimmer.pager.GlimmerHorizontalPager
import androidx.xr.glimmer.pager.GlimmerPagerState
import androidx.xr.glimmer.pager.rememberGlimmerPagerState

val state = rememberGlimmerPagerState(initialPage = 5, pageCount = { 10 })
val scope = rememberCoroutineScope()
Column {
    Button(onClick = { scope.launch { state.scrollToPage(1) } }) {
        Text(text = "Scroll to Page 1")
    }

    GlimmerHorizontalPager(modifier = Modifier.fillMaxSize(), state = state) { page ->
        Card { Text(text = "Page: $page") }
    }
}
Parameters
page: Int

the index of the page to scroll to.

ScrollScope.updateCurrentPage

fun ScrollScope.updateCurrentPage(
    page: Int,
    pageOffsetFraction: @FloatRange(from = -0.5, to = 0.5) Float = 0.0f
): Unit

Jump immediately to a given page with a given pageOffsetFraction inside a ScrollScope. Use this method to create custom animated scrolling experiences. This will update the value of currentPage and currentPageOffsetFraction immediately, but can only be used inside a ScrollScope, use scroll to gain access to a ScrollScope.

Please refer to the sample to learn how to use this API.

import androidx.compose.animation.core.animate
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Modifier
import androidx.xr.glimmer.Button
import androidx.xr.glimmer.Card
import androidx.xr.glimmer.Text
import androidx.xr.glimmer.pager.GlimmerHorizontalPager
import androidx.xr.glimmer.pager.GlimmerPagerState
import androidx.xr.glimmer.pager.rememberGlimmerPagerState

suspend fun GlimmerPagerState.customAnimateScrollToPage(page: Int) {
    val preJumpPosition =
        if (page > currentPage) {
            (page - 1).coerceAtLeast(0)
        } else {
            (page + 1).coerceAtMost(pageCount - 1)
        }
    scroll {
        // Update the target page
        updateTargetPage(page)

        // pre-jump to 1 page before our target page
        updateCurrentPage(preJumpPosition, pageOffsetFraction = 0.0f)
        val targetPageDiff = page - currentPage
        val distance = targetPageDiff * layoutInfo.pageSize.toFloat()
        var previousValue = 0.0f
        animate(0f, distance) { currentValue, _ ->
            previousValue += scrollBy(currentValue - previousValue)
        }
    }
}

val state = rememberGlimmerPagerState(initialPage = 5, pageCount = { 10 })
val scope = rememberCoroutineScope()

Column {
    Button(onClick = { scope.launch { state.customAnimateScrollToPage(1) } }) {
        Text(text = "Scroll to Page 1")
    }

    GlimmerHorizontalPager(modifier = Modifier.fillMaxSize(), state = state) { page ->
        Card { Text(text = "Page: $page") }
    }
}
Parameters
page: Int

The destination page to scroll to

pageOffsetFraction: @FloatRange(from = -0.5, to = 0.5) Float = 0.0f

A fraction of the page size that indicates the offset the destination page will be offset from its snapped position.

ScrollScope.updateTargetPage

fun ScrollScope.updateTargetPage(targetPage: Int): Unit

Used to update targetPage during a programmatic scroll operation. This can only be called inside a ScrollScope and should be called anytime a custom scroll (through scroll) is executed in order to correctly update targetPage. This will not move the pages and it's still the responsibility of the caller to call ScrollScope.scrollBy in order to actually get to targetPage. By the end of the scroll block, when the GlimmerHorizontalPager is no longer scrolling targetPage will assume the value of currentPage.

Please refer to the sample to learn how to use this API.

import androidx.compose.animation.core.animate
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Modifier
import androidx.xr.glimmer.Button
import androidx.xr.glimmer.Card
import androidx.xr.glimmer.Text
import androidx.xr.glimmer.pager.GlimmerHorizontalPager
import androidx.xr.glimmer.pager.GlimmerPagerState
import androidx.xr.glimmer.pager.rememberGlimmerPagerState

suspend fun GlimmerPagerState.customAnimateScrollToPage(page: Int) {
    val preJumpPosition =
        if (page > currentPage) {
            (page - 1).coerceAtLeast(0)
        } else {
            (page + 1).coerceAtMost(pageCount - 1)
        }
    scroll {
        // Update the target page
        updateTargetPage(page)

        // pre-jump to 1 page before our target page
        updateCurrentPage(preJumpPosition, pageOffsetFraction = 0.0f)
        val targetPageDiff = page - currentPage
        val distance = targetPageDiff * layoutInfo.pageSize.toFloat()
        var previousValue = 0.0f
        animate(0f, distance) { currentValue, _ ->
            previousValue += scrollBy(currentValue - previousValue)
        }
    }
}

val state = rememberGlimmerPagerState(initialPage = 5, pageCount = { 10 })
val scope = rememberCoroutineScope()

Column {
    Button(onClick = { scope.launch { state.customAnimateScrollToPage(1) } }) {
        Text(text = "Scroll to Page 1")
    }

    GlimmerHorizontalPager(modifier = Modifier.fillMaxSize(), state = state) { page ->
        Card { Text(text = "Page: $page") }
    }
}

Public properties

canScrollBackward

open val canScrollBackwardBoolean

Whether this pager can scroll backward (is not at the first page).

canScrollForward

open val canScrollForwardBoolean

Whether this pager can scroll forward (has more pages to show).

currentPage

Added in 1.0.0-alpha12
val currentPageInt

The page that sits closest to the snapped position. This is an observable value and will change as the pager scrolls either by gesture or animation.

currentPageOffsetFraction

Added in 1.0.0-alpha12
val currentPageOffsetFractionFloat

Indicates how far the current page is to the snapped position, this will vary from -0.5 (page is offset towards the start of the layout) to 0.5 (page is offset towards the end of the layout). This is 0.0 if the currentPage is in the snapped position. The value will flip once the current page changes.

interactionSource

Added in 1.0.0-alpha12
val interactionSourceInteractionSource

InteractionSource that will be used to dispatch drag events when this pager is being dragged. If you want to know whether the fling (or animated scroll) is in progress, use isScrollInProgress.

isScrollInProgress

Added in 1.0.0-alpha12
open val isScrollInProgressBoolean

Whether this pager is currently scrolling by gesture, fling or animation.

lastScrolledBackward

open val lastScrolledBackwardBoolean

Whether the last scroll action was in the backward direction.

lastScrolledForward

open val lastScrolledForwardBoolean

Whether the last scroll action was in the forward direction.

layoutInfo

Added in 1.0.0-alpha12
val layoutInfoGlimmerPagerLayoutInfo

A GlimmerPagerLayoutInfo that contains information about the Pager's last layout pass.

pageCount

Added in 1.0.0-alpha12
val pageCountInt

The total amount of pages present in this pager.

settledPage

Added in 1.0.0-alpha12
val settledPageInt

The page that is currently "settled". This is an animation/gesture unaware page in the sense that it will not be updated while the pages are being scrolled, but rather when the animation/scroll settles.

targetPage

Added in 1.0.0-alpha12
val targetPageInt

The page that is currently being scrolled towards. This is an observable value and will change as the pager scrolls either by gesture or animation.