I had tried to make a simple animation using Jetpack Compose that when the button click the text must be displayed. The button will move from left-right with rotation and text will get visible coming from right to left. But there is a small problem that's occuring, when I click on button to start animation, my button moves to a different offset value(before starting of animation) suddenly and then it is doing animation and vice-versa for closing of animation.
I don't know why that sudden shift of button is coming while doing animation. I humbly request to help me with this.
This is my composable of animation:
@Composable
fun AnimateWithFadingIn(modifier: Modifier = Modifier){
var isShowing by remember { mutableStateOf(false) }
val iconOffset by animateDpAsState(
targetValue = if (isShowing) 80.dp else (0).dp,
label = "",
animationSpec = tween(durationMillis = 1000)
)
val rotationAngle by animateFloatAsState(
targetValue = if (isShowing) 360f else 0f,
animationSpec = tween(durationMillis = 1000)
)
Column(
modifier = modifier.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
Row {
AnimatedVisibility(
visible = isShowing,
enter = slideInHorizontally(initialOffsetX = {it},animationSpec = tween(durationMillis = 1000)) + fadeIn(animationSpec = tween(durationMillis = 1000)),
exit = slideOutHorizontally (targetOffsetX = {it/2},animationSpec = tween(durationMillis = 1000)) + fadeOut(animationSpec = tween(durationMillis = 1000))
) {
Text("Text is showing")
}
if (isShowing){
Spacer(modifier = Modifier.width(8.dp))
}
IconButton(modifier = Modifier.size(40.dp).offset(x = iconOffset).rotate(degrees = rotationAngle), onClick = {isShowing = !isShowing}) {
Icon(imageVector = Icons.Default.Clear, contentDescription = null)
}
}
}
}
I had tried to make a simple animation using Jetpack Compose that when the button click the text must be displayed. The button will move from left-right with rotation and text will get visible coming from right to left. But there is a small problem that's occuring, when I click on button to start animation, my button moves to a different offset value(before starting of animation) suddenly and then it is doing animation and vice-versa for closing of animation.
I don't know why that sudden shift of button is coming while doing animation. I humbly request to help me with this.
This is my composable of animation:
@Composable
fun AnimateWithFadingIn(modifier: Modifier = Modifier){
var isShowing by remember { mutableStateOf(false) }
val iconOffset by animateDpAsState(
targetValue = if (isShowing) 80.dp else (0).dp,
label = "",
animationSpec = tween(durationMillis = 1000)
)
val rotationAngle by animateFloatAsState(
targetValue = if (isShowing) 360f else 0f,
animationSpec = tween(durationMillis = 1000)
)
Column(
modifier = modifier.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
Row {
AnimatedVisibility(
visible = isShowing,
enter = slideInHorizontally(initialOffsetX = {it},animationSpec = tween(durationMillis = 1000)) + fadeIn(animationSpec = tween(durationMillis = 1000)),
exit = slideOutHorizontally (targetOffsetX = {it/2},animationSpec = tween(durationMillis = 1000)) + fadeOut(animationSpec = tween(durationMillis = 1000))
) {
Text("Text is showing")
}
if (isShowing){
Spacer(modifier = Modifier.width(8.dp))
}
IconButton(modifier = Modifier.size(40.dp).offset(x = iconOffset).rotate(degrees = rotationAngle), onClick = {isShowing = !isShowing}) {
Icon(imageVector = Icons.Default.Clear, contentDescription = null)
}
}
}
}
Share
Improve this question
asked Feb 5 at 23:01
Prakhar_PathakPrakhar_Pathak
991 silver badge8 bronze badges
2 Answers
Reset to default 0based kinda on this
try adding visibilityThreshold = 1.dp
to iconOffset (if it's available, if not try to change it to animateFloatAsState
and store the dp as float)
if it works I will update the answer to explain why that may fix it
By turning on showing the boundaries of the layout you can see that the problem is that AnimatedVisibility, hides/shows the component completely. You can use AnimatedContent and not move the icon anywhere, just rotate it and you can also limit the maximum width of the component (in case the text is multiline), also possible to customize the component resizing animation in using(SizeTransform)
:
@Composable
fun AnimateWithFadingIn(modifier: Modifier = Modifier) {
var isShowing by remember { mutableStateOf(false) }
val rotationAngle by animateFloatAsState(
targetValue = if (isShowing) 360f else 0f,
animationSpec = tween(durationMillis = 1000)
)
Column(
modifier = modifier.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
Row(verticalAlignment = Alignment.CenterVertically) {
AnimatedContent(
targetState = isShowing,
transitionSpec = {
(slideInHorizontally(animationSpec = tween(durationMillis = 1000))
+ fadeIn(animationSpec = tween(durationMillis = 1000)))
.togetherWith(
slideOutHorizontally(animationSpec = tween(durationMillis = 1000))
+ fadeOut(animationSpec = tween(durationMillis = 1000))
)
.using(SizeTransform(sizeAnimationSpec = { _, _ -> tween(durationMillis = 1000) }))
}
) { targetState ->
if (targetState) {
Row(Modifier.widthIn(max = 200.dp)) {
Text(text = "Text is showing\n".repeat(10).dropLast(1))
}
}
}
IconButton(
modifier = Modifier
.size(40.dp)
.rotate(degrees = rotationAngle),
onClick = { isShowing = !isShowing })
{
Icon(imageVector = Icons.Default.Clear, contentDescription = null)
}
}
}
}