Home > Back-end >  Custom CollapsingTopAppBar Jetpack Compose
Custom CollapsingTopAppBar Jetpack Compose

Time:11-06

The essence of the problem is that I want to write my own version of the AppBar that would include content as another Compose function. After looking at the source code of the current CollapsingTopAppBar implementation, I saw the following lines:

@Composable
private fun TwoRowsTopAppBar(
    ...
    scrollBehavior: TopAppBarScrollBehavior?
) {
    ...
    val pinnedHeightPx: Float = 64.dp
    val maxHeightPx: Float = 152.dp

    LocalDensity.current.run {
        pinnedHeightPx = pinnedHeight.toPx()
        maxHeightPx = maxHeight.toPx()
    }
    // Sets the app bar's height offset limit to hide just the bottom title area and keep top title
    // visible when collapsed.
    SideEffect {
        if (scrollBehavior?.state?.heightOffsetLimit != pinnedHeightPx - maxHeightPx) {
            scrollBehavior?.state?.heightOffsetLimit = pinnedHeightPx - maxHeightPx
        }
    }
    ...
    Surface(...) {
        Column {
            TopAppBarLayout(
                ...
                heightPx = pinnedHeightPx
                ...
            )
            TopAppBarLayout(
                ...
                heightPx = maxHeightPx - pinnedHeightPx   (scrollBehavior?.state?.heightOffset
                   ?: 0f),
                ...
            )
        }
    }
}

As I understand it, scrollBehavior is used to handle the collapse and expansion behavior. In the current implementation, just constant values are put in heightOffsetLimit. And since I need my appbar implementation to be able to contain content of any size, I need to somehow know the size of this content in advance and put this value in heightOffsetLimit.

I have already written the code for my AppBar, so that it also contains content. But since I can't pass the height value of the content to scrollBehavior, the AppBar doesn't collapse to the end.

CodePudding user response:

you need to calculate the height that the appbar will have before drawing it into the screen. I have followed this issue and solved my problem with the last solution. hope it helps:

Get height of element Jetpack Compose

  • use the content you can put (ex. an image or a huge text) as the MainContent
  • use your appbar as the DependentContent and use the size given in lambda to give the height to your appbar
  • finally set placeMainContent false as I believe you don't need to draw the image (or any other composable) directly in a box

and you will good to go

  • Related