Skip to content

Instantly share code, notes, and snippets.

@PompaDonpa
Last active August 31, 2022 15:23
Show Gist options
  • Save PompaDonpa/053dca580640038177f40aabddc4e7fb to your computer and use it in GitHub Desktop.
Save PompaDonpa/053dca580640038177f40aabddc4e7fb to your computer and use it in GitHub Desktop.
Composable BottomNavItem - Icon & Text w/animation
@Composable
fun BottomNavItem(
icon: @Composable BoxScope.() -> Unit,
text: @Composable BoxScope.() -> Unit,
animationProgress: () -> Float
// @FloatRange(from = 0.0, to 1.0) animationProgress: Float
) {
Layout(
content = {
Box(
modifier = Modifier.layoutId("icon")
content = icon
)
Box(
modifier = Modifier.layoutId("text")
content = text
)
}
) { measurables, constraints ->
val iconPlaceable = measurables.first { it.layoutIt == "icon" }.measure(constraints)
val textPlaceable = measurables.first { it.layoutId == "text" }.measure(constraints)
placeTextAndIcon(
textPlaceable,
iconPlaceable,
constraints.maxWidth,
constraints.maxHeight,
animationProgress
)
}
}
fun MeasureScope.placeTextAndIcon(
textPlaceable: Placeable,
iconPlaceable: Placeable,
width: Int,
height: Int,
animationProgress: Float
): MeasureResult {
val iconY = (height - iconPlaceable.height) / 2
val textY = (height - textPlaceable.height) / 2
val progress = animationProgress()
val textWidth = textPlaceable.width * progress
val iconX = (width - textWidth - iconPlaceable.width) / 2
val textX = iconX + iconPlaceable.width
return layout(width, height) {
iconPlaceable.placeRelative(iconX.toInt(), iconY)
if (progress != 0f) {
textPlaceable.placeRelative(textX.toInt(), textY)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment