I have an animated-vector
drawable.
I want this animated vector to be animated in loop while this image is showing.
Cannot find a good solution for this.
val image = animatedVectorResource(R.drawable.no_devices_animated)
var atEnd by remember { mutableStateOf(false) }
Image(
painter = image.painterFor(atEnd),
"image",
Modifier.width(150.dp).clickable {
atEnd = !atEnd
},
contentScale = ContentScale.Fit)
When I tap on the image it is animating but then stops. This is kind of an infinite progress.
Leaving my solution here (using compose 1.2.0-alpha07).
Add the dependencies in your build.gradle
dependencies {
implementation "androidx.compose.animation:animation:$compose_version"
implementation "androidx.compose.animation:animation-graphics:$compose_version"
}
And do the following:
@ExperimentalAnimationGraphicsApi
@Composable
fun AnimatedVectorDrawableAnim() {
val image = AnimatedImageVector.animatedVectorResource(R.drawable.avd_anim)
var atEnd by remember { mutableStateOf(false) }
// This state is necessary to control start/stop animation
var isRunning by remember { mutableStateOf(true) }
// The coroutine scope is necessary to launch the coroutine
// in response to the click event
val scope = rememberCoroutineScope()
// This function is called when the component is first launched
// and lately when the button is pressed
suspend fun runAnimation() {
while (isRunning) {
delay(1000) // set here your delay between animations
atEnd = !atEnd
}
}
// This is necessary just if you want to run the animation when the
// component is displayed. Otherwise, you can remove it.
LaunchedEffect(image) {
runAnimation()
}
Image(
painter = rememberAnimatedVectorPainter(image, atEnd),
null,
Modifier
.size(150.dp)
.clickable {
isRunning = !isRunning // start/stop animation
if (isRunning) // run the animation if isRunning is true.
scope.launch {
runAnimation()
}
},
contentScale = ContentScale.Fit,
colorFilter = ColorFilter.tint(Color.Red)
)
}
Case you need to repeat the animation from the start, the only way I find was create two vector drawables like ic_start
and ic_end
using the information declared in the animated vector drawable and do the following:
// this is the vector resource of the start point of the animation
val painter = rememberVectorPainter(
image = ImageVector.vectorResource(R.drawable.ic_start)
)
val animatedPainter = rememberAnimatedVectorPainter(
animatedImageVector = AnimatedImageVector.animatedVectorResource(R.drawable.avd_anim),
atEnd = !atEnd
)
Image(
painter = if (atEnd) painter else animatedPainter,
...
)
So, when the animated vector is at the end position, the static image is drawn. After the delay, the animation is played again. If you need a continuous repetition, set the delay as the same duration of the animation.