I do experimenting with edge to edge design. In my...
# compose
t
I do experimenting with edge to edge design. In my layout i want to use WindowInsets. The problem is now that i implemented an animation that a detail view slides into view and this detail view handles than the statusbar insets from the right. I calculate the correct insets for the containing list view and using the
consumeWindoInsets
modifier so the list does not use the statusbar padding when the detail view is visible. It works more or less. But i think the modifier is at least one frame behind the rendering of the components. As you can see in the video there is a bounce back effect which is not intended by me. Does anyone did this before? Please see my code in the thread.
Copy code
@OptIn(ExperimentalLayoutApi::class)
@Composable
fun ListDetailLayout(
    list: @Composable () -> Unit,
    detail: @Composable (() -> Unit)?
) {
    val density = LocalDensity.current
    val detailVisible by animateFloatAsState(
        targetValue = if (detail != null) 1f else 0f,
        label = "detail visible",
        animationSpec = tween(1000)
    )
    var consumedInsetsFirst by remember { mutableStateOf(PaddingValues()) }
    var consumedInsetsSecond by remember { mutableStateOf(PaddingValues()) }
    Layout(
        content = {
            Box(
                Modifier
                    .layoutId("first")
                    .consumeWindowInsets(consumedInsetsFirst)
            ) {
                list()
            }
            Box(
                Modifier
                    .layoutId("second")
                    .consumeWindowInsets(consumedInsetsSecond)
                ) {
                if (detail!=null) detail()
            }
        }
    ) { measurable, constraints ->
        val firstMeasurable = measurable.first { it.layoutId == "first" }
        val secondMeasurable = measurable.first { it.layoutId == "second" }
        val width = constraints.maxWidth
        val detailWidth = (width * detailVisible / 2f).toInt()
        val listWidth = width - detailWidth
        consumedInsetsFirst = PaddingValues(end = with(density) { detailWidth.toDp() })
        consumedInsetsSecond = PaddingValues(start = with(density) { listWidth.toDp() })
        val firstPlaceable = firstMeasurable.measure(constraints.copy(maxWidth = listWidth))
        val secondPlaceable = secondMeasurable.measure(constraints.copy(maxWidth = width / 2))
        layout(constraints.maxWidth, constraints.maxHeight) {
            firstPlaceable.place(0, 0, 0f)
            secondPlaceable.place(listWidth, 0, 0f)
        }
    }
}
z
I believe it’s because you’re assigning new instances of
PaddingValues
in your layout modifier. This means the new values won’t get passed to
consumeWindowInsets
until the next recomposition which will be the next frame. I think you should create a mutable implementation of
PaddingValues
to avoid having to recompose to pass updates down.
💯 2
t
Thx Zach this sounds promising i will try this.
Yes it solved the issue thank you very much @Zach Klippenstein (he/him) [MOD]
👍🏻 1
115 Views