Hi! Is there a compose analog of `animationDrawabl...
# compose
a
Hi! Is there a compose analog of
animationDrawable
or something which will enable me to have .png images replacing one another?
d
Recommend putting images in an
AnimatedContent
, where each image is associated with one state.
a
Could you, please, give an example? My final goal is to have a starting image transit to middle image and return to starting image - this behaviour is to be expected from one click on the first image.
d
So a click triggers an animation from image 1 -> 2 -> 1? It's doable. Can you give me a mock so I know my understanding is correct?
a
@Doris Liu Yes, that’s right. For now I can go from 1 to 2 like in a code below, but the intended behaviour is 1 -> 2 -> 1
Copy code
var isClicked by remember { mutableStateOf(false) }
val imagePath: String =
    if (isClicked) pressedImagePath else defaultImagePath

AssetImage(
    path = imagePath,
    modifier = Modifier
        .size(68.dp)
        .clickable(enabled = !isDisabled) {
            isClicked = !isClicked
            onClick.invoke()
        })


// AssetImage is just a wrapper around CoilImage()
@Composable
fun AssetImage(
    path: String,
    modifier: Modifier,
    contentScale: ContentScale = ContentScale.Crop,
) {
    val context = LocalContext.current
    val imageLoader = buildImageLoader(context = context)
    CoilImage(
        imageModel = stringResource(id = R.string.assets_path) + path,
        imageLoader = imageLoader,
        modifier = modifier,
        contentScale = contentScale,
    )
}
I tried to use
LaunchedEffect()
but is seems useless for the case, and also
AnimatedContent
as you suggested, but didn’t get the result
I invented a thing with AnimatedContent. It works every odd click. The approach looks as worst practice example though)
d
I'd suggest something like:
Copy code
var isClicked by remember { mutableStateOf(false) }
val transitionState = remember { MutableTransitionState(defaultImagePath) }
val transition = updateTranistion(transitionState)
transition.AnimatedContent(modifier = Modifier
        .clickable(enabled = !isDisabled) {
            isClicked = !isClicked
            transitionState.targetState = if (isClicked) pressedImagePath else defaultImagePath)
            onClick.invoke()
        }
) {
     AssetImage(Modifier.size(68.dp),path = it)
}
I suspect what you are trying to achieve is to change state when pressed, and again when released. If that's the case,
onClick
wouldn't give you enough info.
a
Since the app was just a funny way of greeting colleagues on Programmer’s Day I had a deadline and decided to stop on the approach, which still worked half of the clicks, but that wasn’t too pronounced for users (nobody noticed, they were occupied by the game itself). Nevertheless, I hope to come across animations again and remember to solve this case.
Doris, thank you for your help and advices. I’ll post my half-solution here, may be the idea will be useful for somebody
Copy code
var isClicked by remember { mutableStateOf(false) }

val imagePath: String =
    if (isClicked) pressedImagePath else defaultImagePath
val reversedImagePath: String =
    if (isClicked) defaultImagePath else pressedImagePath

val zIndex = if (isClicked) -1f else 1f

Box {
    AssetImage(
        path = imagePath,
        modifier = Modifier
            .size(68.dp)
            .zIndex(zIndex)
            .clip(RoundedCornerShape(50.dp))
            .clickable(enabled = !isDisabled) {
                isClicked = !isClicked
                onClick.invoke()
            }
    )

    AnimatedContent(targetState = reversedImagePath) { target ->
        AssetImage(path = target, modifier = Modifier
            .size(68.dp)
        )
    }
}
❤️ 1