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.
User is presented an image. Whenever the user taps onto the image, a marker icon is placed on the tapped location.
(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)
)
}
}
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
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 .
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.
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. Instead, I should call the local device density to correctly determine the amount of pixels for the transformation.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.