ContainedLoadingIndicator

Functions summary

Unit
@ExperimentalMaterial3ExpressiveApi
@Composable
ContainedLoadingIndicator(
    modifier: Modifier,
    containerColor: Color,
    indicatorColor: Color,
    containerShape: Shape,
    polygons: List<RoundedPolygon>
)

A Material Design contained loading indicator.

Cmn
Unit
@ExperimentalMaterial3ExpressiveApi
@Composable
ContainedLoadingIndicator(
    progress: () -> Float,
    modifier: Modifier,
    containerColor: Color,
    indicatorColor: Color,
    containerShape: Shape,
    polygons: List<RoundedPolygon>
)

A Material Design contained loading indicator.

Cmn

Functions

ContainedLoadingIndicator

@ExperimentalMaterial3ExpressiveApi
@Composable
fun ContainedLoadingIndicator(
    modifier: Modifier = Modifier,
    containerColor: Color = LoadingIndicatorDefaults.containedContainerColor,
    indicatorColor: Color = LoadingIndicatorDefaults.containedIndicatorColor,
    containerShape: Shape = LoadingIndicatorDefaults.containerShape,
    polygons: List<RoundedPolygon> = LoadingIndicatorDefaults.IndeterminateIndicatorPolygons
): Unit

A Material Design contained loading indicator.

This version of the loading indicator animates and morphs between various shapes as long as the loading indicator is visible. The shapes in this variation are contained within a colored containerShape.

Contained loading indicator
image

It can be created like this:

import androidx.compose.foundation.layout.Column
import androidx.compose.material3.ContainedLoadingIndicator
import androidx.compose.material3.LoadingIndicator
import androidx.compose.ui.Alignment

Column(horizontalAlignment = Alignment.CenterHorizontally) { ContainedLoadingIndicator() }
Parameters
modifier: Modifier = Modifier

the Modifier to be applied to this loading indicator

containerColor: Color = LoadingIndicatorDefaults.containedContainerColor

the loading indicator's container color

indicatorColor: Color = LoadingIndicatorDefaults.containedIndicatorColor

the loading indicator's color

containerShape: Shape = LoadingIndicatorDefaults.containerShape

the loading indicator's container shape

polygons: List<RoundedPolygon> = LoadingIndicatorDefaults.IndeterminateIndicatorPolygons

a list of RoundedPolygons for the sequence of shapes this loading indicator will morph between. The loading indicator expects at least two items in that list.

Throws
IllegalArgumentException

if the polygons list holds less than two items

ContainedLoadingIndicator

@ExperimentalMaterial3ExpressiveApi
@Composable
fun ContainedLoadingIndicator(
    progress: () -> Float,
    modifier: Modifier = Modifier,
    containerColor: Color = LoadingIndicatorDefaults.containedContainerColor,
    indicatorColor: Color = LoadingIndicatorDefaults.containedIndicatorColor,
    containerShape: Shape = LoadingIndicatorDefaults.containerShape,
    polygons: List<RoundedPolygon> = LoadingIndicatorDefaults.DeterminateIndicatorPolygons
): Unit

A Material Design contained loading indicator.

This version of the loading indicator morphs between its polygons shapes by the value of its progress. The shapes in this variation are contained within a colored containerShape.

Contained loading indicator
image

It can be created like this:

import androidx.compose.animation.core.Spring
import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.animation.core.spring
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.requiredHeight
import androidx.compose.foundation.layout.width
import androidx.compose.material3.ContainedLoadingIndicator
import androidx.compose.material3.LoadingIndicator
import androidx.compose.material3.Slider
import androidx.compose.material3.Text
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp

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 },
    )
}

It can also be used as an indicator for a androidx.compose.material3.pulltorefresh.PullToRefreshBox like this:

import androidx.compose.animation.core.LinearOutSlowInEasing
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Refresh
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.ListItem
import androidx.compose.material3.LoadingIndicator
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
import androidx.compose.material3.pulltorefresh.PullToRefreshDefaults
import androidx.compose.material3.pulltorefresh.pullToRefresh
import androidx.compose.material3.pulltorefresh.rememberPullToRefreshState
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.graphics.graphicsLayer

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)
        }
    }
}
Parameters
progress: () -> Float

the progress of this loading indicator, where 0.0 represents no progress and 1.0 represents full progress. Values outside of this range are coerced into the range. The indicator will morph its shapes between the provided polygons according to the value of the progress.

modifier: Modifier = Modifier

the Modifier to be applied to this loading indicator

containerColor: Color = LoadingIndicatorDefaults.containedContainerColor

the loading indicator's container color

indicatorColor: Color = LoadingIndicatorDefaults.containedIndicatorColor

the loading indicator's color

containerShape: Shape = LoadingIndicatorDefaults.containerShape

the loading indicator's container shape

polygons: List<RoundedPolygon> = LoadingIndicatorDefaults.DeterminateIndicatorPolygons

a list of RoundedPolygons for the sequence of shapes this loading indicator will morph between as it progresses from 0.0 to 1.0. The loading indicator expects at least two items in that list.

Throws
IllegalArgumentException

if the polygons list holds less than two items