Мерцающая/скелетная анимация в Android Jetpack Compose

Как я могу создать подобную анимацию для представления загружаемых объектов, спасибо всем. Пример мерцания

Я искал целый день, но информация, которую я нашел, была в представлениях, если кто-нибудь знает зависимость или как это создать, я буду благодарен.

Кстати, поиск compose shimmer в основных поисковых системах очень быстро приведет к появлению множества ресурсов.

CommonsWare 22.08.2024 00:46

Этот вопрос не стоит чьего-то времени на исследование. Поскольку это можно легко найти, и существует множество веб-сайтов с учебными пособиями.

Laser 22.08.2024 10:11
0
2
92
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

вы можете использовать rememberInfiniteTransition, например, простую мерцающую анимацию ниже

val infiniteTransition = rememberInfiniteTransition(label = "")
val skeletonAlpha by infiniteTransition.animateFloat(
    // between these states, the skeleton will flicker
    initialValue = 1f, // skeleton max alpha
    targetValue = 0.5f, // skeleton min alpha
    animationSpec = infiniteRepeatable(
    // every 500ms, but you can change this time 
        animation = tween(500, easing = LinearEasing),
        repeatMode = RepeatMode.Reverse
    ), label = ""
)
Card(modifier = Modifier.alpha(skeletonAlpha))
Ответ принят как подходящий

API-заполнитель аккомпаниатора устарел. Вместо этого вы можете использовать следующую структуру.

@Composable
fun ShimmerEffectBox(
    modifier: Modifier = Modifier, isShow: Boolean = true,
    content: @Composable BoxScope.() -> Unit
) {
    val shimmerColors = listOf(
        Color.LightGray.copy(alpha = 0.6f),
        Color.LightGray.copy(alpha = 0.2f),
        Color.LightGray.copy(alpha = 0.6f)
    )

    val transition = rememberInfiniteTransition(label = "")
    val translateAnim by transition.animateFloat(
        initialValue = 0f, targetValue = 1000f, animationSpec = infiniteRepeatable(
            animation = tween(durationMillis = 1700, delayMillis = 200),
            repeatMode = RepeatMode.Restart
        ), label = ""
    )

    val brush = Brush.linearGradient(
        colors = shimmerColors,
        start = Offset.Zero,
        end = Offset(x = translateAnim, y = translateAnim)
    )


    if (isShow) {
        Box(
            modifier = modifier.background(brush)
        ) {
            Box(modifier = Modifier
                .matchParentSize()
                .graphicsLayer { alpha = 1f })
        }
    } else {
        Box(
            modifier = modifier
        ) {
            content()
        }

    }
}

Использование:

  Row {
            ShimmerEffectBox(
                modifier = Modifier
                    .height(100.dp)
                    .padding(4.dp)
                    .weight(0.3f)
                    .clip(RoundedCornerShape(4.dp)),
                isShow = true
            ) {

                Image(painter = painterResource(id = R.drawable.ic_launcher_background), contentDescription = "")
            }
            ShimmerEffectBox(
                modifier = Modifier
                    .height(100.dp)
                    .padding(4.dp)
                    .weight(0.7f)
                    .clip(RoundedCornerShape(4.dp)),
                isShow = true
            ) {

                Text(
                    text = "Content to display after content has loaded"
                )
            }
        }

Другие вопросы по теме