我第一次学习 Kotlin,并使用 Jetpack Compose 开发一个应用程序来记录考古遗址上的骨头。该应用程序将在不同屏幕尺寸的不同设备上使用。通过打开骨骼图像并单击图像上的复选框以标记已发现的骨骼的特定片段来记录骨骼。为此,必须将复选框准确放置在骨骼上片段的位置。不幸的是,每当我在模拟器上使用不同的设备尺寸进行测试时,复选框的位置就会发生变化。如何相对于图像放置复选框,以便无论屏幕/图像的大小如何,它们都显示在图像上完全相同的坐标中?
我可以通过记录点击事件来提取这些复选框在图像上的相对位置,但似乎无法将它们转换为 Modifier.offset() 的 x 和 y 值。例如,这些是三个复选框应该所在的位置:
2024-09-23 10:38:32.021 5058-5058 Image click com.example.logger D x: 0.5133263, y: 0.37671298
2024-09-23 10:38:33.768 5058-5058 Image click com.example.logger D x: 0.21499948, y: 0.45003778
2024-09-23 10:38:36.898 5058-5058 Image click com.example.logger D x: 0.8219602, y: 0.45003778
下面是我拥有的模板,该模板必须在其中运行该代码。我传入了复选框的选中状态和更改列表(因为它们的数量在骨骼之间有所不同),以及放置每个复选框的坐标列表(在变量坐标中)
BoxWithConstraints(
modifier = Modifier.fillMaxSize().background(MaterialTheme.colorScheme.onSecondaryContainer),
contentAlignment = Alignment.Center
) {
val imageWidth = maxWidth
val imageHeight = maxHeight
Box(
contentAlignment = Alignment.Center
) {
Image(
painter = painterResource(R.drawable.hyd),
contentDescription = "Image of hyoid",
modifier = Modifier.fillMaxSize(0.9f)
)
checkedStates.forEachIndexed { index, checked ->
// position a checkbox
Checkbox(
checked = checked,
onCheckedChange = changes[index],
modifier = Modifier.offset(x = ?, y = ?)
)
)
}
}
}
您可以将屏幕上的 x 坐标计算为
position on Screen = positionX on Bitmap * (Composable width/ Bitmap width)
获取位图尺寸(以 dp 为单位)
val density = LocalDensity.current
val bitmapDpSize: DpSize = with(density) {
painter.intrinsicSize.toDpSize()
}
并使用上面的方程计算图像上的坐标。然而,只有当位图完全适合图像且没有间隙时,这才有效。
如果图像之间有任何间隙,您需要计算可组合位图图像的哪个部分被绘制。为此,您可以参考这个适用于任何 ContentScale 和 Alignment 的答案,包括像
Crop
这样的内容,它可能会裁剪并显示图像内位图的某些部分。