You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现指定的图标垂直翻转旋转动画?(附参考资源)

实现Jetpack Compose底部导航图标垂直翻转动画

我需要实现如下GIF展示的图标动画(或许不该叫“垂直旋转”):
图标垂直翻转动画

我找到过一个底部导航动画示例,但它只是图标弹跳效果,不符合我的需求。我需要的是图标旋转动画,动画过程的中间状态如下:
动画中间状态


解决方案

可以通过Jetpack Compose的animateFloatAsState结合Modifier.graphicsLayer的rotationX属性,实现这种垂直翻转的动画效果,核心是控制图标绕X轴的旋转角度,同时在翻转过程中切换图标或调整视觉效果。

双图标翻转实现(切换图标)

这种实现会在翻转到中间状态时,切换显示另一个图标,和你提供的GIF效果一致:

import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.foundation.Image
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.size
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Home
import androidx.compose.material.icons.filled.Person
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.unit.dp

@Composable
fun FlipNavigationIcon() {
    var isSelected by remember { mutableStateOf(false) }
    
    // 动画过渡旋转角度:未选中0°,选中180°
    val rotationAngle by animateFloatAsState(
        targetValue = if (isSelected) 180f else 0f,
        label = "flip rotation"
    )

    Image(
        // 旋转超过90°时切换图标,模拟翻转显示背面
        imageVector = if (rotationAngle > 90f) Icons.Default.Person else Icons.Default.Home,
        contentDescription = "Navigation icon",
        modifier = Modifier
            .size(48.dp)
            .clickable { isSelected = !isSelected }
            .graphicsLayer {
                rotationX = rotationAngle
                // 调整相机距离,优化透视变形效果
                cameraDistance = 8 * density
            }
    )
}

单图标翻转实现(仅视觉翻转)

如果不需要切换图标,只需要图标自身的翻转效果,可以用以下代码:

import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.material.Icon
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Home
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.unit.dp

@Composable
fun SingleIconFlip() {
    var isSelected by remember { mutableStateOf(false) }
    val rotationAngle by animateFloatAsState(
        targetValue = if (isSelected) 180f else 0f,
        label = "single icon flip"
    )

    Icon(
        imageVector = Icons.Default.Home,
        contentDescription = "Single flip icon",
        modifier = Modifier
            .size(48.dp)
            .clickable { isSelected = !isSelected }
            .graphicsLayer {
                rotationX = rotationAngle
                cameraDistance = 8 * density
                // 翻转时调整透明度,增强视觉层次感
                alpha = if (rotationAngle > 90f) 0.7f else 1f
            }
    )
}

集成到底部导航栏

将上述图标组件替换BottomNavigationItem中的icon参数即可:

import androidx.compose.material.BottomNavigation
import androidx.compose.material.BottomNavigationItem
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue

@Composable
fun AnimatedBottomNavigation() {
    var selectedItem by remember { mutableStateOf(0) }
    val items = listOf("Home", "Profile")

    BottomNavigation {
        items.forEachIndexed { index, item ->
            BottomNavigationItem(
                icon = { FlipNavigationIcon() },
                label = { Text(item) },
                selected = selectedItem == index,
                onClick = { selectedItem = index }
            )
        }
    }
}

内容的提问来源于stack exchange,提问作者user924

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 07:10:38