PullToRefreshCustomIndicatorSample
@Sampled
@Composable
@Preview
fun PullToRefreshCustomIndicatorSample() {
var isRefreshing by remember { mutableStateOf(false) }
val coroutineScope = rememberCoroutineScope()
val state = remember { PullToRefreshState() }
val listState = rememberTransformingLazyColumnState()
val transformationSpec = rememberTransformationSpec()
AppScaffold {
ScreenScaffold(scrollState = listState, timeText = { TimeText() }) { contentPadding ->
PullToRefreshBox(
isRefreshing = isRefreshing,
onRefresh = {
isRefreshing = true
coroutineScope.launch {
delay(2000)
isRefreshing = false
}
},
state = state,
indicator = {
PullToRefreshDefaults.IndicatorBox(
state = state,
isRefreshing = isRefreshing,
shape = MaterialTheme.shapes.medium,
containerColor = MaterialTheme.colorScheme.primaryContainer,
modifier = Modifier.align(Alignment.TopCenter),
) {
if (isRefreshing) {
CircularProgressIndicator(
strokeWidth = 2.5.dp,
colors =
ProgressIndicatorDefaults.colors(
indicatorColor =
MaterialTheme.colorScheme.onPrimaryContainer
),
modifier = Modifier.size(24.dp),
)
} else {
val rotation = state.distanceFraction * 180f
val scale = state.distanceFraction.coerceIn(0f, 1f)
Icon(
imageVector = Icons.Default.Refresh,
contentDescription = "Pull to refresh",
tint = MaterialTheme.colorScheme.onPrimaryContainer,
modifier =
Modifier.size(24.dp).graphicsLayer {
rotationZ = rotation
scaleX = scale
scaleY = scale
},
)
}
}
},
modifier = Modifier.fillMaxSize(),
) {
TransformingLazyColumn(
state = listState,
contentPadding = contentPadding,
modifier = Modifier.fillMaxSize(),
) {
items(10) { index ->
Button(
onClick = {},
label = { Text("Custom item ${index + 1}") },
transformation = SurfaceTransformation(transformationSpec),
modifier =
Modifier.transformedHeight(this, transformationSpec)
.minimumVerticalContentPadding(
ButtonDefaults.minimumVerticalListContentPadding
)
.fillMaxWidth(),
)
}
}
}
}
}
}