onPlaced
Compose Modifier
Common
fun Modifier.onPlaced(onPlaced: (LayoutCoordinates) -> Unit) = this then OnPlacedElement(onPlaced)
Invoke onPlaced
after the parent LayoutModifier
and parent layout has been placed and before
child LayoutModifier
is placed. This allows child LayoutModifier
to adjust its own placement
based on where the parent is.
Code Examples
OnPlaced
@Composable
fun OnPlaced() {
fun Modifier.animatePlacement(): Modifier = composed {
val scope = rememberCoroutineScope()
var targetOffset by remember { mutableStateOf(IntOffset.Zero) }
var animatable by remember {
mutableStateOf<Animatable<IntOffset, AnimationVector2D>?>(null)
}
this.onPlaced {
// Calculate the position in the parent layout
targetOffset = it.positionInParent().round()
}
.offset {
// Animate to the new target offset when alignment changes.
val anim =
animatable
?: Animatable(targetOffset, IntOffset.VectorConverter).also {
animatable = it
}
if (anim.targetValue != targetOffset) {
scope.launch {
anim.animateTo(targetOffset, spring(stiffness = StiffnessMediumLow))
}
}
// Offset the child in the opposite direction to the targetOffset, and slowly catch
// up to zero offset via an animation to achieve an overall animated movement.
animatable?.let { it.value - targetOffset } ?: IntOffset.Zero
}
}
@Composable
fun AnimatedChildAlignment(alignment: Alignment) {
Box(Modifier.fillMaxSize().padding(4.dp).border(1.dp, Color.Red)) {
Box(
modifier =
Modifier.animatePlacement().align(alignment).size(100.dp).background(Color.Red)
)
}
}
}