placeholderShimmer

Functions summary

Modifier
@Composable
Modifier.placeholderShimmer(
    placeholderState: PlaceholderState,
    shape: Shape,
    color: Color
)

Modifier.placeholderShimmer draws a periodic shimmer over content, indicating to the user that contents are loading or potentially out of date.

Functions

Modifier.placeholderShimmer

@Composable
fun Modifier.placeholderShimmer(
    placeholderState: PlaceholderState,
    shape: Shape = PlaceholderDefaults.shape,
    color: Color = PlaceholderDefaults.shimmerColor
): Modifier

Modifier.placeholderShimmer draws a periodic shimmer over content, indicating to the user that contents are loading or potentially out of date. The placeholder shimmer is a 45 degree gradient from Top|Left of the screen to Bottom|Right. The shimmer is coordinated via the animation frame clock which orchestrates the shimmer so that every component will shimmer as the gradient progresses across the screen. NOTE: For animations to work, an AppScaffold should be used.

Example of a Button with icon and a label that put placeholders over individual content slots and then draws a placeholder shimmer over the result:

import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Favorite
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.text.style.TextOverflow
import androidx.wear.compose.material3.ButtonDefaults
import androidx.wear.compose.material3.FilledTonalButton
import androidx.wear.compose.material3.Icon
import androidx.wear.compose.material3.Text
import androidx.wear.compose.material3.placeholder
import androidx.wear.compose.material3.placeholderShimmer
import androidx.wear.compose.material3.rememberPlaceholderState

var labelText by remember { mutableStateOf("") }
var imageVector: ImageVector? by remember { mutableStateOf(null) }
val buttonPlaceholderState =
    rememberPlaceholderState(isVisible = labelText.isEmpty() || imageVector == null)

FilledTonalButton(
    onClick = { /* Do something */ },
    enabled = true,
    modifier = Modifier.fillMaxWidth().placeholderShimmer(buttonPlaceholderState),
    label = {
        Text(
            text = labelText,
            maxLines = 2,
            overflow = TextOverflow.Ellipsis,
            modifier = Modifier.fillMaxWidth().placeholder(buttonPlaceholderState),
        )
    },
    icon = {
        Box(
            modifier =
                Modifier.size(ButtonDefaults.IconSize).placeholder(buttonPlaceholderState)
        ) {
            if (imageVector != null) {
                Icon(
                    imageVector = imageVector!!,
                    contentDescription = "Heart",
                    modifier =
                        Modifier.wrapContentSize(align = Alignment.Center)
                            .size(ButtonDefaults.IconSize)
                            .fillMaxSize(),
                )
            }
        }
    },
)
// Simulate content loading completing in stages
LaunchedEffect(Unit) {
    delay(2000)
    imageVector = Icons.Filled.Favorite
    delay(1000)
    labelText = "A label"
}

Example of a simple text placeholder:

import androidx.compose.foundation.layout.width
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.wear.compose.material3.Text
import androidx.wear.compose.material3.placeholder
import androidx.wear.compose.material3.placeholderShimmer
import androidx.wear.compose.material3.rememberPlaceholderState

var labelText by remember { mutableStateOf("") }
val placeholderState = rememberPlaceholderState(isVisible = labelText.isEmpty())

Text(
    text = labelText,
    overflow = TextOverflow.Ellipsis,
    textAlign = TextAlign.Center,
    modifier =
        Modifier.width(90.dp).placeholderShimmer(placeholderState).placeholder(placeholderState),
)

// Simulate content loading
LaunchedEffect(Unit) {
    delay(3000)
    labelText = "A label"
}
Parameters
placeholderState: PlaceholderState

the current placeholder state that determine whether the placeholder shimmer should be shown.

shape: Shape = PlaceholderDefaults.shape

the shape of the component.

color: Color = PlaceholderDefaults.shimmerColor

the color to use in the shimmer.