Skip to content

PullToRefresh

PullToRefresh is a pull-to-refresh component in COUI that provides refresh functionality for lists and other scrollable content. It features an animated interactive refresh indicator suitable for various scenarios where data refresh is needed.

WARNING

This component is only available in touch-enabled environments.

Import

kotlin
import io.github.suqi8.coui.kmp.basic.PullToRefresh
import io.github.suqi8.coui.kmp.basic.rememberPullToRefreshState

Basic Usage

PullToRefresh can wrap any scrollable content:

kotlin
var isRefreshing by rememberSaveable { mutableStateOf(false) }
val pullToRefreshState = rememberPullToRefreshState()
var items by remember { mutableStateOf(1) }

LaunchedEffect(isRefreshing) {
    if (isRefreshing) {
        delay(500)
        items += 6
        isRefreshing = false
    }
}

Surface {
    PullToRefresh(
        isRefreshing = isRefreshing,
        onRefresh = { isRefreshing = true },
        pullToRefreshState = pullToRefreshState,
    ) {
        LazyColumn(
            modifier = Modifier.fillMaxSize()
        ) {
            items(items) { index ->
                ArrowPreference(
                    title = "Item $index",
                    modifier = Modifier.padding(horizontal = 16.dp),
                    onClick = { /* Click event */ }
                )
            }
        }
    }
}

Contract for isRefreshing

isRefreshing is the hoisted source of truth for the refresh operation. Set it to true in onRefresh when the gesture triggers a refresh, and set it back to false when the data loading completes — lowering it ends the refresh and plays the completion animation. The indicator itself is shown by the pull gesture; PullToRefreshState only manages the visual state.

Component States

PullToRefresh has the following states:

  1. Idle: Initial state, no interaction
  2. Pulling: User is pulling but hasn't reached the refresh threshold
  3. ThresholdReached: Pull threshold reached, release to refresh
  4. Refreshing: Currently refreshing
  5. RefreshComplete: Refresh completed, returning to initial state

Properties

PullToRefresh Properties

Property NameTypeDescriptionDefault ValueRequired
isRefreshingBooleanRefresh stateNoneYes
onRefresh() -> UnitRefresh callback functionNoneYes
modifierModifierContainer modifierModifierNo
pullToRefreshStatePullToRefreshStatePullToRefresh staterememberPullToRefreshState()No
contentPaddingPaddingValuesContent paddingPaddingValues(0.dp)No
topAppBarScrollBehaviorScrollBehaviorTop app bar scroll behaviornullNo
colorColorIndicator color (Unspecified falls back to theme primary)PullToRefreshDefaults.colorNo
circleSizeDpIndicator circle sizePullToRefreshDefaults.circleSizeNo
refreshTextsList<String>Text list for different statesPullToRefreshDefaults.refreshTextsNo
refreshTextStyleTextStyleRefresh text stylePullToRefreshDefaults.refreshTextStyleNo
content@Composable () -> UnitScrollable content composableNoneYes

PullToRefreshState Class

PullToRefreshState manages the UI state of the refresh indicator and can be created using rememberPullToRefreshState() (which takes no parameters). It should only be used for UI state, while refresh logic should be controlled by isRefreshing and onRefresh.

Property NameTypeDescription
refreshStateRefreshStateCurrent visual refresh state
pullProgressFloatPull progress (0-1) relative to the refresh trigger threshold
dragOffsetFloatThe current drag offset in pixels

PullToRefreshDefaults Object

PullToRefreshDefaults provides default values for the component.

Property NameTypeDescriptionDefault Value
colorColorDefault indicator colorColor.Unspecified (falls back to the theme primary color)
circleSizeDpDefault indicator size19.dp
refreshTextsList<String>Default text list["Pull down to refresh", "Release to refresh", "Refreshing...", "Refreshed successfully"]
refreshTextStyleTextStyleDefault text styleTextStyle(fontSize = 14.sp, fontWeight = Bold, color = color)

Advanced Usage

Custom Indicator Color

kotlin
PullToRefresh(
    color = Color.Blue,
    // Other properties
) {
    // Content
}

Custom Refresh Texts

kotlin
PullToRefresh(
    refreshTexts = listOf(
        "Pull to refresh",
        "Release to refresh",
        "Refreshing",
        "Refresh successful",
    ),
    // Other properties
) {
    // Content
}

Coordinating with a TopAppBar

Pass the TopAppBar scroll behavior so the app bar and the pull gesture share nested scroll events:

kotlin
val scrollBehavior = COUIScrollBehavior()

PullToRefresh(
    isRefreshing = isRefreshing,
    onRefresh = { isRefreshing = true },
    topAppBarScrollBehavior = scrollBehavior,
) {
    // Scrollable content
}

Changelog

Released under the Apache-2.0 License