Rotate icon vertically animation

386 Views Asked by At

I'm trying to achieve the animation which is shown on the following GIF (mb I should name it differently, instead of "rotate vertically"):

enter image description here

I found the following example https://blog.devgenius.io/animated-bottom-navigation-in-jetpack-compose-af8f590fbeca but it's not actually the same at all, it just bounces the icon, in my case it should just rotate, so in the middle of its animation it looks like this:

enter image description here

1

There are 1 best solutions below

2
On BEST ANSWER

You can use AnimatedContent composable to achieve this. Simply it holds more than one state and you can give different layouts to each state.

enter image description here

Here is a sample code.

data class BottomNavItem(
    val title: String,
    val icon: ImageVector
)

private val navItems = listOf(
    BottomNavItem(
        "Dashboard",
        Icons.Outlined.Info
    ),
    BottomNavItem(
        "Browse",
        Icons.Outlined.Search
    ),
    BottomNavItem(
        "Profile",
        Icons.Outlined.Person
    )
)

@OptIn(ExperimentalAnimationApi::class)
@Composable
fun AnimatedContentChange() {
    var selectedItemIndex by rememberSaveable { mutableStateOf(0) }

    NavigationBar(modifier = Modifier.fillMaxWidth()) {
        navItems.forEachIndexed { index, item ->
            Box(
                modifier = Modifier
                    .weight(1F)
                    .fillMaxHeight()
                    .clickable {
                        selectedItemIndex = index
                    }, contentAlignment = Alignment.Center
            ) {
                Column(
                    horizontalAlignment = Alignment.CenterHorizontally,
                    verticalArrangement = Arrangement.spacedBy(4.dp, Alignment.CenterVertically)
                ) {
                    val selected = selectedItemIndex == index

                    AnimatedContent(selected, transitionSpec = {
                        slideInVertically { if (selected) -it else it } with slideOutVertically { if (selected) it else -it }
                    }) { isSelected ->
                        Box(
                            modifier = Modifier
                                .padding(vertical = 2.dp)
                                .size(36.dp)
                                .clip(RoundedCornerShape(8.dp))
                                .background(if (isSelected) Color.Blue else Color.LightGray),
                            contentAlignment = Alignment.Center
                        ) {
                            Icon(
                                imageVector = item.icon,
                                contentDescription = null,
                                tint = if (isSelected) Color.White else Color.Blue,
                                modifier = Modifier.fillMaxSize(.5F)
                            )
                        }
                    }
                    Text(text = item.title)
                }
            }
        }
    }
}