简体   繁体   English

Jetpack Compose:在 PointerScope 中使用 Offset

[英]Jetpack Compose: Usage of Offset in PointerScope

I'm having issues understanding how exactly Offset works in Compose, specifically in the PointerScope onTap callback function to track the exact location where the user tapped on a UI element.我在理解Offset在 Compose 中的确切工作原理时遇到问题,特别是在PointerScope onTap回调 function 中跟踪用户点击 UI 元素的确切位置。

Use Case用例

User is presented an image.向用户呈现图像。 Whenever the user taps onto the image, a marker icon is placed on the tapped location.每当用户点击图像时,都会在点击的位置放置一个标记图标

Code代码

(You can ignore the button here, it does nothing at this point) (你可以忽略这里的按钮,此时它什么都不做)

class MainActivity : ComponentActivity() {

//private var editMode = false

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    setContent {

        val offset = remember {
            mutableStateOf(Offset.Infinite)
        }

        MyLayout(offset.value) {
            offset.value = it
        }
    }
}

@Composable
private fun MyLayout(
    offset: Offset,
    saveLastTap: (Offset) -> Unit
) {
    val painter: Painter = painterResource(id = R.drawable.landscape)

    Column(Modifier.fillMaxSize()) {

        Box(
            modifier = Modifier
                .weight(0.95f)
                .fillMaxSize()
        ) {
            Image(
                contentScale = FillBounds,
                painter = painter,
                contentDescription = "",
                modifier = Modifier
                    .pointerInput(Unit) {
                    detectTapGestures(
                        onTap = {
                            saveLastTap(it)
                        }
                    )
                }.border(5.dp, Color.Red)
            )
            
            if (offset.isFinite) {
                PlaceMarkerOnImage(offset = offset)
            }
        }
        Button(
            enabled = false,
            onClick = { TODO("Button Impl") },
            modifier = Modifier.weight(0.05f),
            shape = MaterialTheme.shapes.small
        ) {
            Text(text = "Edit Mode")
        }

    }
}

@Composable
private fun PlaceMarkerOnImage(offset: Offset) {
    Image(
        painter = painterResource(id = R.drawable.marker),
        contentScale = ContentScale.Crop,
        contentDescription = "",
        modifier = Modifier.offset(offset.x.dp, offset.y.dp)
    )
}
}

Outcome结果

I added a little dot to the screenshots to indicate where i tapped.我在屏幕截图中添加了一个小点以指示我点击的位置。 You see the image is getting placed far off the expected locations您会看到图像被放置在远离预期位置的地方

截图1 截图2

Assumptions假设

I read a bit about the Offset object and i suspect the difference has something to do with the conversion to .dp which i need to feed the offset to the marker image Modifier .我阅读了一些关于Offset量 object 的信息,我怀疑这种差异与转换为.dp 有关,我需要将偏移量提供给标记图像修改器。

It might also be related to coordinates being related to it's parent views or something, but since in my example theres nothing else in the UI but the image, i can't grasp this as a possible candidate.它也可能与与其父视图或其他东西相关的坐标有关,但由于在我的示例中 UI 中除了图像之外没有其他任何东西,所以我无法将其作为可能的候选对象。

Any help appreciated.任何帮助表示赞赏。 Thank you !谢谢 !

I just solved it by replacing我只是通过更换解决了它

modifier = Modifier.offset( offset.x.dp, offset.y.dp )

with

modifier = Modifier.offset(
     x= LocalDensity.current.run{offset.x.toInt().toDp()},
     y= LocalDensity.current.run{offset.y.toInt().toDp()} )

Turned out my mistake was that I ignored the properties of dp by just casting the pixel value to dp.原来我的错误是我忽略了 dp 的属性,只是将像素值转换为 dp。 Instead, I should call the local device density to correctly determine the amount of pixels for the transformation.相反,我应该调用本地设备密度来正确确定转换的像素数量。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM