pullRefreshIndicatorTransform

Functions summary

Modifier

A modifier for translating the position and scaling the size of a pull-to-refresh indicator based on the given PullRefreshState.

Cmn

Functions

Modifier.pullRefreshIndicatorTransform

@ExperimentalMaterialApi
fun Modifier.pullRefreshIndicatorTransform(
    state: PullRefreshState,
    scale: Boolean = false
): Modifier

A modifier for translating the position and scaling the size of a pull-to-refresh indicator based on the given PullRefreshState.

import androidx.compose.animation.core.animate
import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.CircularProgressIndicator
import androidx.compose.material.ListItem
import androidx.compose.material.Surface
import androidx.compose.material.Text
import androidx.compose.material.pullrefresh.pullRefresh
import androidx.compose.material.pullrefresh.pullRefreshIndicatorTransform
import androidx.compose.material.pullrefresh.rememberPullRefreshState
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.rotate
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp

val refreshScope = rememberCoroutineScope()
var refreshing by remember { mutableStateOf(false) }
var itemCount by remember { mutableStateOf(15) }

fun refresh() =
    refreshScope.launch {
        refreshing = true
        delay(1500)
        itemCount += 5
        refreshing = false
    }

val state = rememberPullRefreshState(refreshing, ::refresh)
val rotation = animateFloatAsState(state.progress * 120)

Box(Modifier.fillMaxSize().pullRefresh(state)) {
    LazyColumn {
        if (!refreshing) {
            items(itemCount) { ListItem { Text(text = "Item ${itemCount - it}") } }
        }
    }

    Surface(
        modifier =
            Modifier.size(40.dp)
                .align(Alignment.TopCenter)
                .pullRefreshIndicatorTransform(state)
                .rotate(rotation.value),
        shape = RoundedCornerShape(10.dp),
        color = Color.DarkGray,
        elevation = if (state.progress > 0 || refreshing) 20.dp else 0.dp,
    ) {
        Box {
            if (refreshing) {
                CircularProgressIndicator(
                    modifier = Modifier.align(Alignment.Center).size(25.dp),
                    color = Color.White,
                    strokeWidth = 3.dp,
                )
            }
        }
    }
}
Parameters
state: PullRefreshState

The PullRefreshState which determines the position of the indicator.

scale: Boolean = false

A boolean controlling whether the indicator's size scales with pull progress or not.