如何在Jetpackcompose中制作FlipCard动画

我有一个现有的应用程序,我在 XML 中使用 Objectanimator 实现了如下所示的 FlipCard 动画。如果我点击一张卡片,它会水平翻转。但现在我想将它迁移到 jetpack compose。那么是否可以在 jetpack compose 中制作翻盖动画?

更新

最后,我已经结束了这个。虽然我不知道这是否正确,但我得到了我想要的。如果有更好的替代方案,您可以提出建议。谢谢你。

方法一:使用animate*AsState

    @Composable
    fun FlipCard() {
        
        var rotated by remember { mutableStateOf(false) }

        val rotation by animateFloatAsState(
            targetValue = if (rotated) 180f else 0f,
            animationSpec = tween(500)
        )

        val animateFront by animateFloatAsState(
            targetValue = if (!rotated) 1f else 0f,
            animationSpec = tween(500)
        )

        val animateBack by animateFloatAsState(
            targetValue = if (rotated) 1f else 0f,
            animationSpec = tween(500)
        )

        val animateColor by animateColorAsState(
            targetValue = if (rotated) Color.Red else Color.Blue,
            animationSpec = tween(500)
        )

        Box(
            Modifier.fillMaxSize(),
            contentAlignment = Alignment.Center
        ) {
            Card(
                Modifier
                    .fillMaxSize(.5f)
                    .graphicsLayer {
                        rotationY = rotation
                        cameraDistance = 8 * density
                    }
                    .clickable {
                        rotated = !rotated
                    },
                backgroundColor = animateColor
            )
            {
                Column(
                    Modifier.fillMaxSize(),
                    horizontalAlignment = Alignment.CenterHorizontally,
                    verticalArrangement = Arrangement.Center
                ) {

                    Text(text = if (rotated) "Back" else "Front", 
                         modifier = Modifier
                        .graphicsLayer {
                            alpha = if (rotated) animateBack else animateFront
                            rotationY = rotation
                        })
                }

            }
        }
    }

方法二:封装一个Transition并使其可重用。您将获得与方法 1 相同的输出。但它是可重用的,并且适用于复杂的情况。


    enum class BoxState { Front, Back }

    @Composable
    fun AnimatingBox(
        rotated: Boolean,
        onRotate: (Boolean) -> Unit
    ) {
        val transitionData = updateTransitionData(
            if (rotated) BoxState.Back else BoxState.Front
        )
        Card(
            Modifier
                .fillMaxSize(.5f)
                .graphicsLayer {
                    rotationY = transitionData.rotation
                    cameraDistance = 8 * density
                }
                .clickable { onRotate(!rotated) },
            backgroundColor = transitionData.color
        )
        {
            Column(
                Modifier.fillMaxSize(),
                horizontalAlignment = Alignment.CenterHorizontally,
                verticalArrangement = Arrangement.Center
            ) {
                Text(text = if (rotated) "Back" else "Front", 
                     modifier = Modifier
                    .graphicsLayer {
                        alpha =
                            if (rotated) transitionData.animateBack else transitionData.animateFront
                        rotationY = transitionData.rotation
                    })
            }

        }
    }


    private class TransitionData(
        color: State<Color>,
        rotation: State<Float>,
        animateFront: State<Float>,
        animateBack: State<Float>
    ) {
        val color by color
        val rotation by rotation
        val animateFront by animateFront
        val animateBack by animateBack
    }


    @Composable
    private fun updateTransitionData(boxState: BoxState): TransitionData {
        val transition = updateTransition(boxState, label = "")
        val color = transition.animateColor(
            transitionSpec = {
                tween(500)
            },
            label = ""
        ) { state ->
            when (state) {
                BoxState.Front -> Color.Blue
                BoxState.Back -> Color.Red
            }
        }
        val rotation = transition.animateFloat(
            transitionSpec = {
                tween(500)
            },
            label = ""
        ) { state ->
            when (state) {
                BoxState.Front -> 0f
                BoxState.Back -> 180f
            }
        }

        val animateFront = transition.animateFloat(
            transitionSpec = {
                tween(500)
            },
            label = ""
        ) { state ->
            when (state) {
                BoxState.Front -> 1f
                BoxState.Back -> 0f
            }
        }
        val animateBack = transition.animateFloat(
            transitionSpec = {
                tween(500)
            },
            label = ""
        ) { state ->
            when (state) {
                BoxState.Front -> 0f
                BoxState.Back -> 1f
            }
        }

        return remember(transition) { TransitionData(color, rotation, animateFront, animateBack) }
    }


输出

以上是如何在Jetpackcompose中制作FlipCard动画的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>