Build apps faster with our new App builder! Check it out →

onPlaced

Common

Modifier in Compose Ui

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.

Last updated:

Installation

dependencies {
   implementation("androidx.compose.ui:ui:1.8.0-alpha04")
}

Overloads

@Stable
fun Modifier.onPlaced(onPlaced: (LayoutCoordinates) -> Unit)

Code Example

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)
            )
        }
    }
}
by @alexstyl