Hi I am working on a project where I am trying to place markers on images, sort of similar to google maps.
For each marker I will save coordinates and details in the database and whenever the user clicks on the marker, it shows the relevant data, right now I’m only using static sample data though. I’m new to android studio but have managed to put something together, but I’m having a couple of problems.
My main problem is getting the correct offset relative to the image. Also due to different screen sizes and auto resizing of the images, I’m trying to figure out how to tackle that issue as well. The current offset on click is showing high numbers up to around 1200, which makes the markers appear off screen. The current emulator device only goes up to around 200F
width. So I’m not sure how to handle this dynamically for all devices.
Another issue I’m having is the (sample) data not showing when I click the annotation.
ImageScreen.kt –
@Composable
fun ImageScreen(
navController: NavController
) {
//val configuration = LocalConfiguration.current
//val screenHeight = configuration.screenHeightDp.dp
//val screenWidth = configuration.screenWidthDp.dp
val context = LocalContext.current
var xyCoordinates by remember { mutableStateOf(Offset.Zero) }
val sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true)
val scope = rememberCoroutineScope()
var showBottomSheet by remember { mutableStateOf(false) }
val imgAnnotations = remember {
mutableStateListOf<ImgAnnotation>()
.apply {
add(
ImgAnnotation(
uid = "45224",
coordinateX = 10f,
coordinateY = 10f,
note = "Sample text 1"
)
)
add(
ImgAnnotation(
uid = "6454",
coordinateX = 50f,
coordinateY = 50f,
note = "Sample text 2"
)
)
add(
ImgAnnotation(
uid = "211111",
coordinateX = 200f,
coordinateY = 90f,
note = "Sample text 3"
)
)
add(
ImgAnnotation(
uid = "21555",
coordinateX = 32f,
coordinateY = 93f,
note = "Sample text 4"
)
)
}
}
var currentAnnotationSelected = ImgAnnotation()
var showAnnotation by remember { mutableStateOf(false) }
Column(
modifier = Modifier
.fillMaxSize(),
verticalArrangement = Arrangement.Bottom,
horizontalAlignment = Alignment.CenterHorizontally
) {
Box(
contentAlignment = Alignment.Center,
modifier = Modifier.fillMaxSize()
) {
Image(
painter = painterResource(R.drawable.hair_picture),
contentDescription = "Record image",
contentScale = ContentScale.Fit,
modifier = Modifier
.align(Alignment.BottomCenter)
.pointerInput(Unit) {
detectTapGestures(
onPress = { offset ->
xyCoordinates = offset
showBottomSheet = true
}
)
}
)
Box(
contentAlignment = Alignment.Center,
modifier = Modifier.fillMaxSize()
) {
imgAnnotations.forEach { item ->
// val itemX = item.coordinateX
/* Text(
"$itemX",
modifier = Modifier
.offset(item.coordinateX.dp, item.coordinateY.dp)
)*/
MakeShape(
modifier = Modifier
.offset(item.coordinateX.dp, item.coordinateY.dp)
.clickable {
currentAnnotationSelected = item
showAnnotation = true
showBottomSheet = true
},
shape = CircleShape,
size = 20.dp,
bg = Color.Yellow
)
}
}
if (showBottomSheet) {
ModalBottomSheet(
onDismissRequest = {
showBottomSheet = false
showAnnotation = false
currentAnnotationSelected = ImgAnnotation()
},
sheetState = sheetState,
windowInsets = WindowInsets(0, 0, 0, 0)
) {
IconButton(
onClick = {
scope.launch { sheetState.hide() }.invokeOnCompletion {
if (!sheetState.isVisible) {
showBottomSheet = false
showAnnotation = false
currentAnnotationSelected = ImgAnnotation()
}
}
},
modifier = Modifier
.align(Alignment.End)
) {
Icon(
painterResource(R.drawable.close_icon),
contentDescription = "Close icon",
modifier = Modifier.height(18.dp)
)
}
AnnotationNote(
xy = xyCoordinates,
annotationData = currentAnnotationSelected,
show = showAnnotation
)
Spacer(modifier = Modifier.height(16.dp))
}
}
}
}
}
Annotation note composable –
@Composable
fun AnnotationNote(
xy: Offset = Offset.Zero,
show: Boolean = false,
annotationData: ImgAnnotation = ImgAnnotation()
) {
var annotationNote by remember {
mutableStateOf(annotationData.note ?: "")
}
Column(
modifier = Modifier
.fillMaxWidth(),
verticalArrangement = Arrangement.SpaceBetween,
horizontalAlignment = Alignment.CenterHorizontally
) {
if (show) {
Text(annotationNote)
} else {
//Text("$xy")
TextField(
modifier = Modifier.fillMaxWidth(),
value = annotationNote,
onValueChange = {
annotationNote = it
},
label = {
Text(text = "Annotation Note")
}
)
Spacer(modifier = Modifier.height(24.dp))
ActionButton(
onClick = { },
contentColor = Color.Black,
disabledContentColor = Color.Black,
text = stringResource(R.string.save_btn),
)
Spacer(modifier = Modifier.height(24.dp))
}
}
}