Shimer animation does not occur on all items
Hello! First of all, congratulations on the project.
I'm testing the implementation in my multiplatform compose project and I noticed that the shimer animation doesn't occur on all items using LazyRow or Lazycolumn.
Is there anything I can do to make the animation appear on all items?
version: 1.0.10 compose-multiplatform = "1.8.0-rc01"
fun Modifier.shimmerPlaceholder(
visible: Boolean = false,
color: Color = Color(0xFFede8ee),
shape: RoundedCornerShape = RoundedCornerShape(4.dp),
highlightColor: Color = Color.White,
animationDurationMillis: Int = 1000
): Modifier {
return this.placeholder(
visible = visible,
color = color,
shape = shape,
highlight = PlaceholderHighlight.shimmer(
highlightColor = highlightColor,
animationSpec = infiniteRepeatable(
animation = tween(durationMillis = animationDurationMillis),
repeatMode = RepeatMode.Restart
)
)
)
}
LazyColumn(
modifier = Modifier
.fillMaxSize()
.padding(horizontal = 16.dp),
contentPadding = PaddingValues(
bottom = paddingValues.calculateBottomPadding()
),
verticalArrangement = Arrangement.spacedBy(16.dp)
) {
items(state.courses) {
VerticalCourseItemUI(
course = it,
isLoadingEffect = state.isLoading,
onClick = { navigateToCourseDetailsScreen(it.id ?: 0) }
)
}
}
https://github.com/user-attachments/assets/86a83ad3-e5b9-4632-8b53-d545df34594c
Where are you using Modifier.shimmerPlaceholder?
In some parts of my VerticalCourseItemUI component
@Composable
fun VerticalCourseItemUI(
modifier: Modifier = Modifier,
course: Course,
isLoadingEffect: Boolean = false,
colors: CardColors = CardDefaults.cardColors(
containerColor = MyTheme.colorScheme.screen.backgroundSecondary
),
onClick: () -> Unit
) {
Card(
onClick = onClick,
modifier = modifier
.fillMaxWidth(),
shape = RoundedCornerShape(12.dp),
colors = colors,
border = borderStrokeDefault(),
content = {
Row(
modifier = Modifier
.fillMaxWidth()
) {
ImageUI(
modifier = Modifier
.size(80.dp)
.padding(
start = 16.dp,
top = 16.dp
)
.shimmerPlaceholder(
visible = isLoadingEffect,
shape = RoundedCornerShape(12)
),
imageModel = course.cover,
contentScale = ContentScale.Crop,
shape = RoundedCornerShape(12),
onClick = onClick
)
Column(
modifier = Modifier
.fillMaxWidth()
.padding(16.dp),
verticalArrangement = Arrangement.SpaceBetween
) {
Text(
text = course.title ?: "",
modifier = Modifier
.shimmerPlaceholder(visible = isLoadingEffect),
style = TextStyle(
lineHeight = 20.sp,
fontFamily = UrbanistFamily(),
fontWeight = FontWeight(700),
color = MyTheme.colorScheme.text.primaryColor
),
maxLines = 2,
overflow = TextOverflow.Ellipsis
)
VerticalSpacer(size = 8)
Text(
text = course.subtitle ?: "",
modifier = Modifier
.shimmerPlaceholder(visible = isLoadingEffect),
style = TextStyle(
fontSize = 12.sp,
fontFamily = UrbanistFamily(),
color = Greyscale500Color
),
maxLines = 2,
overflow = TextOverflow.Ellipsis
)
VerticalSpacer(size = 12)
Row(
modifier = Modifier
.fillMaxWidth()
.shimmerPlaceholder(visible = isLoadingEffect),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.End
) {
Text(
text = DecimalFormat.format(
value = 289.9f
),
style = TextStyle(
fontSize = 12.sp,
fontFamily = UrbanistFamily(),
color = Greyscale500Color,
letterSpacing = 0.2.sp,
textDecoration = TextDecoration.LineThrough
)
)
HorizontalSpacer(size = 8)
Text(
text = DecimalFormat.format(
value = course.price
),
style = TextStyle(
fontSize = 20.sp,
lineHeight = 25.2.sp,
fontFamily = UrbanistFamily(),
fontWeight = FontWeight(700),
color = MyTheme.colorScheme.defaultColor,
letterSpacing = 0.2.sp
)
)
}
VerticalSpacer(size = 12)
Row(
modifier = Modifier
.fillMaxWidth()
.shimmerPlaceholder(visible = isLoadingEffect),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.SpaceBetween
) {
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(8.dp)
) {
Icon(
painter = getDrawableIllustration(type = IllustrationType.IC_STAR_LINE),
contentDescription = null,
modifier = Modifier
.size(16.dp),
tint = MyTheme.colorScheme.icon.default
)
Text(
text = "5.0",
style = TextStyle(
fontSize = 12.sp,
lineHeight = 22.4.sp,
fontFamily = UrbanistFamily(),
fontWeight = FontWeight(500),
color = MyTheme.colorScheme.icon.default,
letterSpacing = 0.2.sp
)
)
}
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(8.dp)
) {
Icon(
painter = getDrawableIllustration(type = IllustrationType.IC_USERS_LINE),
contentDescription = null,
modifier = Modifier
.size(16.dp),
tint = MyTheme.colorScheme.icon.default
)
Text(
text = "10.598",
style = TextStyle(
fontSize = 12.sp,
lineHeight = 22.4.sp,
fontFamily = UrbanistFamily(),
fontWeight = FontWeight(500),
color = MyTheme.colorScheme.icon.default,
letterSpacing = 0.2.sp
)
)
}
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(8.dp)
) {
Icon(
painter = getDrawableIllustration(type = IllustrationType.IC_TIME_LINE),
contentDescription = null,
modifier = Modifier
.size(16.dp),
tint = MyTheme.colorScheme.icon.default
)
Text(
text = "102h",
style = TextStyle(
fontSize = 12.sp,
lineHeight = 22.4.sp,
fontFamily = UrbanistFamily(),
fontWeight = FontWeight(500),
color = MyTheme.colorScheme.icon.default,
letterSpacing = 0.2.sp
)
)
}
}
}
}
}
)
}
Looks like it should work.
Can you try using the placeholder modifier directly, and let me know if that works?
using only modifier.placeholder also occurs
import com.eygraber.compose.placeholder.PlaceholderHighlight
import com.eygraber.compose.placeholder.material.placeholder
import com.eygraber.compose.placeholder.material.shimmer
@Composable
fun VerticalCourseItemUI(
modifier: Modifier = Modifier,
course: Course,
isLoadingEffect: Boolean = false,
colors: CardColors = CardDefaults.cardColors(
containerColor = MyTheme.colorScheme.screen.backgroundSecondary
),
onClick: () -> Unit
) {
Card(
onClick = onClick,
modifier = modifier
.fillMaxWidth(),
shape = RoundedCornerShape(12.dp),
colors = colors,
border = borderStrokeDefault(),
content = {
Row(
modifier = Modifier
.fillMaxWidth()
) {
ImageUI(
modifier = Modifier
.size(80.dp)
.padding(
start = 16.dp,
top = 16.dp
)
.placeholder(
visible = isLoadingEffect,
shape = RoundedCornerShape(12),
highlight = PlaceholderHighlight.shimmer()
),
imageModel = course.cover,
contentScale = ContentScale.Crop,
previewPlaceholder = painterResource(Res.drawable.course_example_image),
shape = RoundedCornerShape(12),
onClick = onClick
)
Column(
modifier = Modifier
.fillMaxWidth()
.padding(16.dp),
verticalArrangement = Arrangement.SpaceBetween
) {
Text(
text = course.title ?: "",
modifier = Modifier
.placeholder(
visible = isLoadingEffect,
highlight = PlaceholderHighlight.shimmer()
),
style = TextStyle(
lineHeight = 20.sp,
fontFamily = UrbanistFamily(),
fontWeight = FontWeight(700),
color = MyTheme.colorScheme.text.primaryColor
),
maxLines = 2,
overflow = TextOverflow.Ellipsis
)
VerticalSpacer(size = 8)
Text(
text = course.subtitle ?: "",
modifier = Modifier
.placeholder(
visible = isLoadingEffect,
highlight = PlaceholderHighlight.shimmer()
),
style = TextStyle(
fontSize = 12.sp,
fontFamily = UrbanistFamily(),
color = Greyscale500Color
),
maxLines = 2,
overflow = TextOverflow.Ellipsis
)
VerticalSpacer(size = 12)
Row(
modifier = Modifier
.fillMaxWidth()
.placeholder(
visible = isLoadingEffect,
highlight = PlaceholderHighlight.shimmer()
),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.End
) {
Text(
text = DecimalFormat.format(
value = 289.9f
),
style = TextStyle(
fontSize = 12.sp,
fontFamily = UrbanistFamily(),
color = Greyscale500Color,
letterSpacing = 0.2.sp,
textDecoration = TextDecoration.LineThrough
)
)
HorizontalSpacer(size = 8)
Text(
text = DecimalFormat.format(
value = course.price
),
style = TextStyle(
fontSize = 20.sp,
lineHeight = 25.2.sp,
fontFamily = UrbanistFamily(),
fontWeight = FontWeight(700),
color = MyTheme.colorScheme.defaultColor,
letterSpacing = 0.2.sp
)
)
}
VerticalSpacer(size = 12)
Row(
modifier = Modifier
.fillMaxWidth()
.placeholder(
visible = isLoadingEffect,
highlight = PlaceholderHighlight.shimmer()
),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.SpaceBetween
) {
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(8.dp)
) {
Icon(
painter = getDrawableIllustration(type = IllustrationType.IC_STAR_LINE),
contentDescription = null,
modifier = Modifier
.size(16.dp),
tint = MyTheme.colorScheme.icon.default
)
Text(
text = "5.0",
style = TextStyle(
fontSize = 12.sp,
lineHeight = 22.4.sp,
fontFamily = UrbanistFamily(),
fontWeight = FontWeight(500),
color = MyTheme.colorScheme.icon.default,
letterSpacing = 0.2.sp
)
)
}
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(8.dp)
) {
Icon(
painter = getDrawableIllustration(type = IllustrationType.IC_USERS_LINE),
contentDescription = null,
modifier = Modifier
.size(16.dp),
tint = MyTheme.colorScheme.icon.default
)
Text(
text = "10.598",
style = TextStyle(
fontSize = 12.sp,
lineHeight = 22.4.sp,
fontFamily = UrbanistFamily(),
fontWeight = FontWeight(500),
color = MyTheme.colorScheme.icon.default,
letterSpacing = 0.2.sp
)
)
}
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(8.dp)
) {
Icon(
painter = getDrawableIllustration(type = IllustrationType.IC_TIME_LINE),
contentDescription = null,
modifier = Modifier
.size(16.dp),
tint = MyTheme.colorScheme.icon.default
)
Text(
text = "102h",
style = TextStyle(
fontSize = 12.sp,
lineHeight = 22.4.sp,
fontFamily = UrbanistFamily(),
fontWeight = FontWeight(500),
color = MyTheme.colorScheme.icon.default,
letterSpacing = 0.2.sp
)
)
}
}
}
}
}
)
}
https://github.com/user-attachments/assets/4b823ca0-41db-46b3-b449-7b45c9ec73b9
Ok I will look into it. Thanks for the report.
It's possible that the issue is the library is still using CMP 1.7.3
Otherwise I'm not sure what could be causing the issue. What KMP target is this happening on?
compose-multiplatform = "1.8.0-rc01"
The KMP target, meaning Android, ios, Desktop, etc...
Android, ios
Sorry I thought I had responded to this. I released v1.0.11 last month which uses Compose 1.8.0. Can you try with that and see if the issue is resolved?
I just tested version 1.0.11 and it still happens. It happens when I move quickly in lists
OK I will take a look again.
I think https://github.com/eygraber/compose-placeholder/pull/335 might fix this. Can you try the latest SNAPSHOT and let me know if that works?
Solved. Thank you very much for your help.