I am a newbie in android Kotlin development, it would be really appreciable, if someone can help me out. I already spent more than a week on the research of jetpack compose animation.
I have been trying to create a control where the circle has to given a pulsating animation and that needs to be controlled with various states or configuration. As a note - the animation is not only for a single circle, it has to be with multiple circle for different states.
I was able to implement the required animation with infiniteTransition, but that that doesn’t meet my requirement as it animates infinitely. I have given the code that I tried.
            @Composable
fun InfinitelyFlowingCircles() {
    val primaryColor = MaterialTheme.colors.primary
    val midCircle = primaryColor.copy(0.50f)
    DrawCircleOnCanvas(
        scale = scaleInfiniteTransition(initialValue = 0.5f, targetValue = 1f, durationMillis = 1000),
        color = midCircle,
        radiusRatio = 2f
    )
}
@Composable
private fun DrawCircleOnCanvas(
    scale: Float,
    color: Color,
    radiusRatio: Float
) {
    Canvas(
        modifier = Modifier
            .fillMaxSize()
            .graphicsLayer {
                scaleX = scale
                scaleY = scale
            }
    ) {
        val canvasWidth = size.width
        val canvasHeight = size.height
        drawCircle(
            color = color,
            center = Offset(
                x = canvasWidth / 2,
                y = canvasHeight / 2
            ),
            radius = size.minDimension / radiusRatio,
        )
    }
}
@Composable
private fun scaleInfiniteTransition(
    initialValue: Float = 0f,
    targetValue: Float,
    durationMillis: Int,
): Float {
    val infiniteTransition = rememberInfiniteTransition()
    val scale: Float by infiniteTransition.animateFloat(
        initialValue = initialValue,
        targetValue = targetValue,
        animationSpec =  infiniteRepeatable(
            animation = tween(durationMillis, easing = LinearEasing),
            repeatMode = RepeatMode.Reverse
        )
    )
    return scale
}
Also, I have tried a finite animation which works well, but I could find an option to get the finishListener in that animation so that I couldn't find a way to start the next animation. The code for the same has mentioned below.
   @Composable
fun UpdateTransition() {
    var circleState by remember {
        mutableStateOf(CircleState.Small)
    }
    val transition = updateTransition(
        targetState = circleState, label =
        "Circle Transition"
    )
    val color by transition.animateColor(label = "Color") { state ->
        when (state) {
            CircleState.Small -> Color.Blue
            CircleState.Large -> Color.Red
        }
    }
    val size by transition.animateDp(label = "Size") { state ->
        when (state) {
            CircleState.Small -> 100.dp
            CircleState.Large -> 200.dp
        }
    }
        Box(
            Modifier
                .clip(CircleShape)
                .size(size)
                .background(color)
                .clickable(
                    onClick = {
                        circleState = when (circleState) {
                            CircleState.Small -> CircleState.Large
                            CircleState.Large -> CircleState.Small
                        }
                    })
        ) {
        }
}
				
                        
You could use Animatable.