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

Jetpack Compose修改Image旋转支点至边缘实现动画效果

Compose修改图片旋转支点为边缘的解决方案

我需要实现箭头图片的旋转动画,目前已能让图片旋转,但默认以图片中心为支点,希望改为以图片底部边缘为支点(如预期效果所示)。尝试过Canvas但未取得进展,求可行的修改方法。

当前代码

Column() {
    Box(
        modifier = Modifier
            .size(160.dp),
        contentAlignment = Alignment.Center
    ) {
        IconButton(
            onClick = {
                rotation = 270
            }, modifier = Modifier
                .rotate(315f)
                .offset(x = 0.dp, y = -60.dp)
        ) {
            Icon(
                imageVector = Icons.Default.Home, contentDescription = "",
                modifier = Modifier
            )
        }

        IconButton(
            onClick = {
                rotation = 315
            }, modifier = Modifier
                .rotate(0f)
                .offset(x = 0.dp, y = -60.dp)
        ) {
            Icon(
                imageVector = Icons.Default.Favorite, contentDescription = "",
                modifier = Modifier
            )
        }

        IconButton(
            onClick = {
                rotation = 0
            }, modifier = Modifier
                .rotate(45f)
                .offset(x = 0.dp, y = -60.dp)
        ) {
            Icon(
                imageVector = Icons.Default.Person, contentDescription = "",
                modifier = Modifier
            )
        }

        Box(
            modifier = Modifier
                .size(70.dp)
                .background(color = Color.Red, shape = CircleShape)
                .align(Alignment.Center),
        ) {
            Image(
                modifier = Modifier.size(24.dp).align(Alignment.Center).rotate(angle),
                painter = painterResource(id = R.drawable.gender_arrow), contentDescription = ""
            )
        }
    }
}

效果对比

预期效果

预期旋转动画效果

当前效果

当前旋转效果

解决方案

修改旋转支点核心方法

Compose的rotate修饰符默认以元素中心为旋转支点,若要自定义支点,需使用graphicsLayer直接控制旋转参数:

  1. 替换原rotate修饰符为graphicsLayer
  2. 将旋转支点设为图片底部中心:rotationPivotX取图片宽度的一半,rotationPivotY取图片高度(即底部边缘位置)

修改后的Image代码:

Box(
    modifier = Modifier
        .size(70.dp)
        .background(color = Color.Red, shape = CircleShape)
        .align(Alignment.Center),
) {
    Image(
        painter = painterResource(id = R.drawable.gender_arrow),
        contentDescription = "",
        modifier = Modifier
            .size(24.dp)
            .align(Alignment.Center)
            .graphicsLayer {
                rotation = angle
                // 支点设为图片底部中心
                rotationPivotX = size.width / 2f
                rotationPivotY = size.height
            }
    )
}

补充平滑动画(可选)

为了让旋转过渡更自然,建议使用animateFloatAsState实现状态动画:

// 定义状态变量
var rotation by remember { mutableIntStateOf(0) }
val angle by animateFloatAsState(
    targetValue = rotation.toFloat(),
    animationSpec = tween(durationMillis = 500) // 动画时长500ms
)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 08:23:15