https://kotlinlang.org logo
#compose
Title
# compose
v

Vaibhav Jaiswal

03/05/2024, 10:46 AM
I am facing an issue, where the first time my screen opens I get
WindowInsets.statusBar
and
WindowInsets.navigationBar
paddings as 0 But when I open that screen again it then gets the correct padding
s

Stylianos Gakis

03/05/2024, 12:13 PM
What do you mean by “Open that screen again”
v

Vaibhav Jaiswal

03/05/2024, 12:13 PM
Navigate to some other screen and come back
s

Stylianos Gakis

03/05/2024, 12:15 PM
Don’t see a reason this would happen besides you consuming the insets already at a composable higher up in the tree so they are 0 at that time. Also some screenshots and/or code might help show what’s wrong.
v

Vaibhav Jaiswal

03/05/2024, 1:45 PM
@Stylianos Gakis All I am doing is
WindowInsets.statusBar.asPaddingValues()
, and its 0, Window Insets are not being consumed anywhere up the heirarchy, as I am drawing
edgeToEdge()
s

Stylianos Gakis

03/05/2024, 1:46 PM
There’s no need to ping me again if I am already in the conversation
That is not the only way for insets to already be consumed. A parent composable may have already used up those insets. Without screenshots and code this is I think impossible to help you further
You can also try to make a minimal project which just reproduces what you are describing here to see where exactly this goes wrong
v

Vaibhav Jaiswal

03/05/2024, 1:58 PM
Copy code
In composable: 
val scrollBehaviour = rememberHideAppBarScrollBehaviour(
            height = APP_BAR_HEIGHT.dp,
            windowInsets = WindowInsets.statusBars,
            hideDirection = HideDirection.UP
        )

enum class HideDirection {
    UP, DOWN
}



class HideAppBarScrollBehaviour(
    private val height: Dp,
    density: Density,
    windowInsets: WindowInsets,
    hideDirection: HideDirection
) {
    var heightOffset by mutableStateOf(0f)
        private set


    private val insetsPaddingPx = when (hideDirection) {
        HideDirection.UP -> windowInsets.getTop(density)
        HideDirection.DOWN -> windowInsets.getBottom(density)
    }

    private val insetsPadding = with(density) {
        insetsPaddingPx.toDp()
    }

    private val heightPx = with(density) {
        height.toPx() + insetsPaddingPx
    }

    /**
     * A value that represents the collapsed height percentage of the app bar.
     * A 0.0 represents a fully expanded bar, and 1.0 represents a fully collapsed bar (computed as heightOffset / heightOffsetLimit).
     */
    val collapsedFraction: Float
        get() = (if (heightPx != 0f) heightOffset / heightPx
        else 0f).let { if (it < 0) -it else it }


    val nestedScrollConnection = object : NestedScrollConnection {
        override fun onPreScroll(available: Offset, source: NestedScrollSource): Offset {
            val delta = available.y
            val newOffset = heightOffset + delta
            heightOffset = newOffset.coerceIn(-heightPx, 0f)

            return Offset.Zero
        }
    }

    @Composable
    fun contentPaddingAnimated() = animateDpAsState(
        targetValue = (height + insetsPadding) * (1 - collapsedFraction)
    )
}

@Composable
fun rememberHideAppBarScrollBehaviour(
    height: Dp,
    windowInsets: WindowInsets,
    hideDirection: HideDirection
): HideAppBarScrollBehaviour {
    val density = LocalDensity.current
    return remember {
        HideAppBarScrollBehaviour(
            height = height,
            density = density,
            windowInsets = windowInsets,
            hideDirection = hideDirection
        )
    }
}
This is how I am using it
the insets here is 0, now when I navigate and come back, the insets has the correct value
s

Stylianos Gakis

03/05/2024, 2:07 PM
The one thing that from an initial read looks wrong to me from all this is remember here without passing any keys to it
Copy code
@Composable
fun rememberHideAppBarScrollBehaviour(
    height: Dp,
    windowInsets: WindowInsets,
    hideDirection: HideDirection
): HideAppBarScrollBehaviour {
    val density = LocalDensity.current
    return remember {
        HideAppBarScrollBehaviour(
            height = height,
            density = density,
            windowInsets = windowInsets,
            hideDirection = hideDirection
        )
    }
}
If any of the inputs change you simply do not re-create the
HideAppBarScrollBehaviour
class with the new information. It retains whatever stale information you had before. Is this what you want here?
v

Vaibhav Jaiswal

03/05/2024, 2:08 PM
None of them would change I call it like this
Copy code
val scrollBehaviour = rememberHideAppBarScrollBehaviour(
            height = APP_BAR_HEIGHT.dp,
            windowInsets = WindowInsets.statusBars,
            hideDirection = HideDirection.UP
        )
s

Stylianos Gakis

03/05/2024, 2:09 PM
And what is it that goes wrong exactly, which value is not what you expect it to be? Was there a video for this too?
v

Vaibhav Jaiswal

03/07/2024, 8:58 AM
see the app bar and bottom nav
2 Views