A Material Design contained loading indicator.
ContainedLoadingIndicatorSample
@OptIn(ExperimentalMaterial3ExpressiveApi::class)
@Preview
@Composable
fun ContainedLoadingIndicatorSample() {
Column(horizontalAlignment = Alignment.CenterHorizontally) { ContainedLoadingIndicator() }
}
DeterminateContainedLoadingIndicatorSample
@OptIn(ExperimentalMaterial3ExpressiveApi::class)
@Preview
@Composable
fun DeterminateContainedLoadingIndicatorSample() {
var progress by remember { mutableFloatStateOf(0f) }
val animatedProgress by
animateFloatAsState(
targetValue = progress,
animationSpec =
spring(
dampingRatio = Spring.DampingRatioNoBouncy,
stiffness = Spring.StiffnessVeryLow,
visibilityThreshold = 1 / 1000f,
),
)
Column(horizontalAlignment = Alignment.CenterHorizontally) {
ContainedLoadingIndicator(progress = { animatedProgress })
Spacer(Modifier.requiredHeight(30.dp))
Text("Set loading progress:")
Slider(
modifier = Modifier.width(300.dp),
value = progress,
valueRange = 0f..1f,
onValueChange = { progress = it },
)
}
}
LoadingIndicatorPullToRefreshSample
@OptIn(ExperimentalMaterial3Api::class, ExperimentalMaterial3ExpressiveApi::class)
@Composable
@Preview
fun LoadingIndicatorPullToRefreshSample() {
var itemCount by remember { mutableStateOf(15) }
var isRefreshing by remember { mutableStateOf(false) }
val state = rememberPullToRefreshState()
val coroutineScope = rememberCoroutineScope()
val onRefresh: () -> Unit = {
isRefreshing = true
coroutineScope.launch {
// fetch something
delay(5000)
itemCount += 5
isRefreshing = false
}
}
val scaleFraction = {
if (isRefreshing) 1f
else LinearOutSlowInEasing.transform(state.distanceFraction).coerceIn(0f, 1f)
}
Scaffold(
modifier =
Modifier.pullToRefresh(
state = state,
isRefreshing = isRefreshing,
onRefresh = onRefresh,
),
topBar = {
TopAppBar(
title = { Text("TopAppBar") },
// Provide an accessible alternative to trigger refresh.
actions = {
IconButton(onClick = onRefresh) {
Icon(Icons.Filled.Refresh, "Trigger Refresh")
}
},
)
},
) {
Box(Modifier.padding(it)) {
LazyColumn(Modifier.fillMaxSize()) {
if (!isRefreshing) {
items(itemCount) { ListItem({ Text(text = "Item ${itemCount - it}") }) }
}
}
Box(
Modifier.align(Alignment.TopCenter).graphicsLayer {
scaleX = scaleFraction()
scaleY = scaleFraction()
}
) {
PullToRefreshDefaults.LoadingIndicator(state = state, isRefreshing = isRefreshing)
}
}
}
}