0

我正在尝试将基于视图的代码转换为 Compose。我有一个可组合的,它将图像(画家)作为参数并使用图像可组合显示它。我想要的是,每当参数值发生变化时,我的图像应该进行 360 度旋转,并且图像应该在角度约为 1 时发生变化。180度(即动画中途)

这是我制作的可组合。

@Composable
fun MyImage(displayImage: Painter) {
    Image(
        painter = displayImage,
        contentDescription = null,
        modifier = Modifier
            .size(36.dp)
            .clip(CircleShape)
    )
}

现在,当displayImage更改时,新图像立即显示,没有任何动画(显然)。如何实现所需的动画?

我试图转换的代码如下所示:

fun onImageChange(imageRes: Int) {
    ObjectAnimator.ofFloat(imageView, View.ROTATION, 0f, 360f)
        .apply {
            addUpdateListener {
                if (animatedFraction == 0.5f) {
                    imageView.setImageResource(imageRes)
                }
            }
            start()
        }
}
4

1 回答 1

1

可以使用Animatable.

Compose 动画基于协程,因此您可以等待animateTo挂起函数完成,更改图像并运行另一个动画。这是一个基本示例:

var flag by remember { mutableStateOf(true) }
val resourceId = remember(flag) { if (flag) R.drawable.profile else R.drawable.profile_inverted }
val rotation = remember { Animatable(0f) }
val scope = rememberCoroutineScope()

Column(Modifier.padding(30.dp)) {
    Button(onClick = {
        scope.launch {
            rotation.animateTo(
                targetValue = 180f,
                animationSpec = tween(1000, easing = LinearEasing)
            )
            flag = !flag
            rotation.animateTo(
                targetValue = 360f,
                animationSpec = tween(1000, easing = LinearEasing)
            )
            rotation.snapTo(0f)
        }
    }) {
        Text("Rotate")
    }
    Image(
        painterResource(id = resourceId),
        contentDescription = null,
        modifier = Modifier
            .size(300.dp)
            .rotate(rotation.value)
    )
}

输出:

如果要为不断变化的图像设置动画,则必须将两个图像放入 a 中Box,并在它们旋转时再使用一个 为这两个图像的不透明度设置动画Animatable

于 2021-10-25T10:55:38.237 回答