Android Jetpack Compose(可组合)用动画更改图像源

sla*_*boy 6 android android-animation android-jetpack-compose

我有一个矢量可绘制对象通过图像的画家属性设置为源。现在我想更改源,但也要为更改设置动画。我所说的动画并不是指使用路径数据变形动画,而是想要具有简单的淡入、淡出效果。因此,一旦源更改,我希望隐藏先前的源并使用淡入淡出动画显示当前的可绘制对象。

在此输入图像描述

现在我正在做一个解决方法,我使用 2 个图像以及两个不同图像的源,并使用AnimatedVisibility来更改图像的可见性,以匹配主题。是否有改变动画源的标准方法?

这是我使用的 hack,我认为它非常丑陋

@OptIn(ExperimentalAnimationApi::class)
@Composable
fun AnimatedImage(modifier: Modifier, isLightTheme: Boolean, srcLight: Int = R.drawable.ic_sun, srcDark: Int = R.drawable.ic_moon) {

    val colors = LocalColors.current
    val (enter, exit) = remember {
        arrayListOf(
            fadeIn(animationSpec = tween(durationMillis = 1500)),
            fadeOut(animationSpec = tween(durationMillis = 500))
        )
    }

    AnimatedVisibility(
        visible = !isLightTheme,
        enter = enter as EnterTransition,
        exit = exit as ExitTransition
    ) {
        Image(
            painter = painterResource(id = srcDark), contentDescription = "",
            colorFilter = ColorFilter.tint(colors.secondsArrow),
            modifier = modifier
        )
    }

    AnimatedVisibility(
        visible = isLightTheme,
        enter = enter,
        exit = exit
    ) {
        Image(
            painter = painterResource(id = srcLight), contentDescription = "",
            colorFilter = ColorFilter.tint(colors.secondsArrow),
            modifier = modifier
        )
    }
}
Run Code Online (Sandbox Code Playgroud)

Phi*_*hov 12

您可以使用基本Crossfade动画:

Crossfade(
    flag,
    animationSpec = tween(1000)
) { targetState ->
    Image(
        painterResource(if (targetState) R.drawable.ic_redo else R.drawable.ic_undo),
        contentDescription = null,
        modifier = Modifier.background(Color.Black)
    )
}
Run Code Online (Sandbox Code Playgroud)

或者,如果您需要更复杂的,您可以使用AnimatedContent- 我的示例相当于您的 double- AnimatedVisibility

AnimatedContent(
    flag,
    transitionSpec = {
        fadeIn(animationSpec = tween(durationMillis = 1500)) with
                fadeOut(animationSpec = tween(durationMillis = 500))
    }
) { targetState ->
    Image(
        painterResource(if (targetState) R.drawable.ic_redo else R.drawable.ic_undo),
        contentDescription = null,
        modifier = Modifier.background(Color.Black)
    )
}
Run Code Online (Sandbox Code Playgroud)

请注意,在这两种情况下都需要使用targetState传入的内容 lambda,因为该 lambda 在转换期间会被多次重组。

您可以在 Compose Animation文档中找到更多信息