我试图在Jetpack Compose中创建一个半圆速度进度条.除非视图是正方形,否则半圆看起来不会像预期的那样,如果我使用1:2宽度:高度,它将变平.我想要一个可组合的,代表半个圆,在那里我没有不可用的视图下半部分.

    Box(
        modifier = modifier
            .background(Color.Red)
    ) {
        Canvas(modifier = Modifier.size(300.dp)) {
            drawArc(
                color = Color.LightGray,
                -180f,
                180f,
                useCenter = false,
                style = Stroke(8.dp.toPx(), cap = StrokeCap.Round)
            )
        }
        Text(
            modifier = Modifier.align(alignment = Alignment.Center),
            text = "20 Mbps",
            color = Color.White,
            fontSize = 20.sp
        )
    }

enter image description here

预期结果将是一个可重用的半圆,其高度与实际半圆相同,因此我可以轻松地根据它定位其他内容.预期的视图大小由绿色虚线标记.

enter image description here

推荐答案

正如我在 comments 中提到的那样,如果你想要一个覆盖整个高度的半弧,弧使用矩形,只要是你画弧高度的两倍

@Composable
private fun ArcComposable(modifier: Modifier) {
    Box(
        modifier = modifier
            .background(Color.Red)
    ) {
        Canvas(modifier = Modifier
            .size(300.dp)
            .clipToBounds()) {
            drawArc(
                color = Color.LightGray,
                -180f,
                180f,
                useCenter = false,
                size = Size(size.width, size.height * 2),
                style = Stroke(8.dp.toPx(), cap = StrokeCap.Round)
            )
        }
        Text(
            modifier = Modifier.align(alignment = Alignment.Center),
            text = "20 Mbps",
            color = Color.White,
            fontSize = 20.sp
        )
    }
}

我添加了修饰符.clipToBounds(),因为默认情况下会将strokeCap round添加到线的长度.您只需减少尺寸和高度几像素,以匹配画布内部.默认情况下,画布即使不使用大小设置修改器,也会绘制超出其边界的任何内容,除非使用Modifier.clipToBounds()

enter image description here

private fun ArcComposable(modifier: Modifier) {
    Box(
        modifier = modifier
            .background(Color.Red)
    ) {
        Canvas(
            modifier = Modifier
                .size(300.dp)
//            .clipToBounds()
        ) {
            drawArc(
                color = Color.LightGray,
                -180f,
                180f,
                useCenter = false,
                topLeft = Offset(4.dp.toPx(), 6.dp.toPx()),
                size = Size(size.width - 8.dp.toPx(), size.height * 2 - 20.dp.toPx()),
                style = Stroke(8.dp.toPx(), cap = StrokeCap.Round)
            )
        }
        Text(
            modifier = Modifier.align(alignment = Alignment.Center),
            text = "20 Mbps",
            color = Color.White,
            fontSize = 20.sp
        )
    }
}

Android相关问答推荐

如何让用户与我的应用生成的多个音频文件交互

将Android Studio插件复制到离线网络

有人能帮我在应用程序上使用模拟位置时避免被发现吗?我已经反编译并粘贴了一个代码,S小文件

try 用Jetpack Compose理解视图模型和导航

如何从sqlite数据库中检索数据到碎片android?

Android手柄注射周期错误,多个模块引用一个核心模块

在内部创建匿名对象的繁忙循环调用函数会产生开销吗?

AndroidX Media3 迁移指南

Play store 的 Play 完整性与 Firebase 应用判断 Play 完整性

如何使用 Wea​​r OS 上的运行状况服务模拟位置?

同样的参数值下,为什么requiredSizeIn不等于requiredWidthIn + requiredHeightIn?

Android Jetpack Compose 电视焦点恢复

运行设备选项卡在 Android Studio 中自动打开

在 Material 3 TopAppBar 代码的哪个位置定义了填充?

如何从 firebase 实时数据库中检索最后一个值

服务似乎在启动时忽略传递的变量

在 Jetpack Compose 中自动滚动后面的项目

如何正确地将图像上传到 Jetpack Compose 中的 LazyList 中的项目?

在 Jetpack Compose 中更改列中子项的对齐方式

在 Room 中创建一对多关系时,@Relation 类是什么意思?