最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

android - Why animation is not working as expected? - Stack Overflow

programmeradmin1浏览0评论

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
Add a comment  | 

2 Answers 2

Reset to default 0

based 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)
            }
        }
    }
}
发布评论

评论列表(0)

  1. 暂无评论