Skip to content

Instantly share code, notes, and snippets.

@vitoksmile
Created February 11, 2025 18:07
Show Gist options
  • Select an option

  • Save vitoksmile/ef95dcb79394ba1d3f5b4272c418a93c to your computer and use it in GitHub Desktop.

Select an option

Save vitoksmile/ef95dcb79394ba1d3f5b4272c418a93c to your computer and use it in GitHub Desktop.
ComposeHints
@Composable
internal fun HintsContainer(
modifier: Modifier,
anchors: () -> List<HintAnchorState>,
) {
val anchors = anchors()
Layout(
modifier = modifier
.overlayBackground(anchors),
content = {
anchors.forEach { it.hint.content() }
},
) { measurables, constraints ->
// Measure each hint
val placeables = measurables.map { measurable ->
measurable.measure(
constraints.copy(minWidth = 0, minHeight = 0)
)
}
// Set the size of the layout as big as it can
layout(constraints.maxWidth, constraints.maxHeight) {
// Place each hint relatively to it's anchor
placeables.forEachIndexed { index, placeable ->
val anchor = anchors[index]
// Center align this hint
val x = (anchor.offset.x.toInt() - (placeable.width - anchor.size.width) / 2)
// Fix the coordinate if it's out of the screen
.coerceAtLeast(0)
.coerceAtMost(constraints.maxWidth - placeable.width)
// Put this hint below its anchor
var y = (anchor.offset.y.toInt() + anchor.size.height)
// Fix y-coordinate if it's out of the screen
.coerceAtMost(constraints.maxHeight - placeable.height)
if (y < anchor.offset.y + anchor.size.height) {
// Hint is be overlapping its anchor, put this hint above its anchor
y = anchor.offset.y.toInt() - placeable.height
}
placeable.placeRelative(x = x, y = y)
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment