Graphics Shapes:程序化多边形与 Morph · AndroidX 源码指南
AAndroidX 源码指南
图形与动画
图形与动画 · androidx.graphics.shapes

Graphics Shapes:程序化多边形与 MorphShapes 1.2.0-alpha01

用 RoundedPolygon 生成形状、变换到 UI 坐标,并在两个形状之间 Morph。

最后更新 2026-08-01

复制即用

生成形状并转换为 Compose Path:

import androidx.compose.ui.graphics.Path
import androidx.graphics.shapes.RoundedPolygon
import androidx.graphics.shapes.circle
import androidx.graphics.shapes.rectangle
import androidx.graphics.shapes.star
import androidx.graphics.shapes.transformed

val circle = RoundedPolygon.circle()
val rect = RoundedPolygon.rectangle(width = 2f, height = 1f)
val star = RoundedPolygon.star(numVertices = 5, innerRadius = 0.5f)

// 移动到目标区域并缩放
val placed = star.transformed {
    translate(width / 2f, height / 2f)
    scale(width / 2f, height / 2f)
}
val path: Path = placed.toPath()

形状之间 Morph:

import androidx.compose.ui.graphics.Path
import androidx.graphics.shapes.Morph
import androidx.graphics.shapes.RoundedPolygon
import androidx.graphics.shapes.circle
import androidx.graphics.shapes.star

val morph = Morph(RoundedPolygon.circle(), RoundedPolygon.star())

fun pathAt(progress: Float): Path = morph.toPath(progress = progress)

progress 0..1 表示从起点形状到终点形状的插值位置,由动画状态驱动。

动画驱动 Morph

@Composable
fun MorphAnimation() {
    var progress by remember { mutableFloatStateOf(0f) }

    LaunchedEffect(Unit) {
        while (true) {
            progress = 0f
            animate(0f, 1f, animationSpec = tween(2000)) { value, _ ->
                progress = value
            }
        }
    }

    val path = remember(progress) {
        Morph(RoundedPolygon.circle(), RoundedPolygon.star())
            .toPath(progress = progress)
    }

    Canvas(Modifier.fillMaxSize()) {
        drawPath(path)
    }
}

形状构造速查

工厂参数说明
circle()numVertices(默认 8)、radius圆形
rectangle()width、height、rounding矩形/圆角矩形
star()numVertices、innerRadius星形
pill()药丸形
pillStar()numVertices、innerRadius药丸星

常见陷阱

  • 忘 transformed:默认 2x2 包围盒(中心 0,0),不位移缩放画出来很小/偏移。
  • Morph 起点终点不同顶点数:可能变形不自然,选顶点数一致的形状。
  • 每帧重建 polygon:高成本,remember 缓存。

要点

  • RoundedPolygon.circle() 默认 8 个顶点;star() 需要 numVerticesinnerRadius
  • 默认形状位于 2x2 包围盒(中心 0,0),绘制前必须用 transformed {} 做位移和缩放。
  • toPath() 转 Compose Path 可直接绘制;Morph.toPath(progress) 做形状插值。
  • 动画驱动 Morph 用 animate + remember(progress) 缓存。

相关页面