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

如何用Jetpack Compose实现人体线条图内部的百分比填充?

实现人体线条图的进度填充方案

一、核心实现思路

你用的是非矩形线条PNG,直接用Image组件很难实现内部区域的进度填充。最灵活的方式是将PNG转为VectorDrawable矢量图,这样可以直接获取线条勾勒的路径,再通过Canvas实现按进度填充。

二、线条图制作/转换方案

  • 从零制作:用Figma、Adobe Illustrator等设计工具绘制人体矢量线条,导出为SVG格式,再通过Android Studio的Vector Asset Studio导入为VectorDrawable(路径:File > New > Vector Asset)。
  • 已有PNG转换:用SVG转换工具将PNG转为SVG,手动清理冗余路径后转成VectorDrawable,务必保证路径是闭合的(填充功能依赖闭合路径)。

三、Compose代码实现

假设你已将线条图转为VectorDrawable(命名为ic_male),以下是完整的进度填充实现:

@Composable
fun WaterTracing() {
    // 管理填充进度,0f-1f对应0%-100%
    val fillProgress = rememberSaveable { mutableStateOf(0f) }

    Column(
        modifier = Modifier.fillMaxSize(),
        verticalArrangement = Arrangement.Center,
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        // 用Canvas绘制矢量路径并实现进度填充
        Canvas(modifier = Modifier.size(500.dp)) {
            // 加载VectorDrawable并获取路径
            val vectorPainter = painterResource(id = R.drawable.ic_male) as VectorPainter
            val path = vectorPainter.path

            // 计算填充区域:用进度裁剪路径
            val pathMeasure = PathMeasure()
            pathMeasure.setPath(path, false)
            val segmentPath = Path()
            pathMeasure.getSegment(0f, pathMeasure.length * fillProgress.value, segmentPath)
            segmentPath.close()

            // 绘制线条轮廓
            drawPath(
                path = path,
                color = Color.Black,
                style = Stroke(width = 2.dp.toPx())
            )

            // 绘制填充区域(蓝色,按进度显示)
            drawPath(
                path = segmentPath,
                color = Color(0xFF2196F3)
            )
        }

        Button(onClick = {
            // 首次点击设置为20%,之后可按需累加
            if (fillProgress.value == 0f) {
                fillProgress.value = 0.2f
            } else {
                // 可选:每次点击额外增加20%,不超过100%
                fillProgress.value = min(fillProgress.value + 0.2f, 1f)
            }
        }) {
            Text(text = "DRINK WATER")
        }
    }
}

四、关键细节说明

  • 确保VectorDrawable的路径是闭合的,否则填充会失效。如果导出的SVG路径不闭合,可在设计工具中手动闭合路径。
  • PathMeasure用于截取路径的指定长度段,实现进度式填充。如果需要模拟从底部往上填充的喝水效果,可以调整getSegment的起始和结束参数。
  • 若坚持使用PNG而非矢量图,可通过Bitmap获取轮廓路径,但步骤更复杂且精度不足,不推荐。

内容的提问来源于stack exchange,提问作者Yunus Emrah Uluçay

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 11:37:50