Search code examples
androidandroid-jetpack-composeandroid-collapsingtoolbarlayout

Implement CollapsingToolbar using Jetpack compose


I am trying to implement collapsing toolbar in my Detail screen using Jetpack compose.

val toolbarHeightPx = with(LocalDensity.current) {
        278.dp.roundToPx().toFloat()
    }
    val toolbarOffsetHeightPx = remember { mutableStateOf(0f) }
    val nestedScrollConnection = remember {
        object : NestedScrollConnection {
            override fun onPreScroll(available: Offset, source: NestedScrollSource): Offset {
                val delta = available.y
                val newOffset = toolbarOffsetHeightPx.value + delta
                toolbarOffsetHeightPx.value = newOffset.coerceIn(-toolbarHeightPx, 0f)
                return Offset.Zero
            }
        }
    }

    Box(
        Modifier
            .fillMaxSize()
            // attach as a parent to the nested scroll system
            .nestedScroll(nestedScrollConnection)
    ) {
        DetailsContent(
            scrollState = scrollState,
            onNamePosition = { newNamePosition ->
                // Comparing to Float.MIN_VALUE as we are just interested on the original
                // position of name on the screen
                if (detailScroller.namePosition == Float.MIN_VALUE) {
                    detailScroller =
                        detailScroller.copy(namePosition = newNamePosition)
                }
            },
            item = item,
            boxHeight = with(LocalDensity.current) {
                440.dp + toolbarOffsetHeightPx.value.toDp()
            },
            imageHeight = with(LocalDensity.current) {
                420.dp + toolbarOffsetHeightPx.value.toDp()
            },
            sendNotification = sendNotification,
            contentAlpha = { contentAlpha.value }
        )
        DetailsToolbar(
            toolbarState, item.name, pressOnBack,
            contentAlpha = { contentAlpha.value }
        )
    }

The idea is taken from sunflower Google Github project. When we scroll up it works as expected but when we scroll down, it will not sometimes fully scrolled. toolbarOffsetHeightPx should become 0 when we scroll down, but sometimes it is a negative value that cause image does not fully scrolled. It is not stable at all and 0 or any negative value may happen. it happens since we have :

boxHeight = with(LocalDensity.current) {
                440.dp + toolbarOffsetHeightPx.value.toDp()
            },
imageHeight = with(LocalDensity.current) {
                420.dp + toolbarOffsetHeightPx.value.toDp()
            }

Why is that and how to resolve it?


Solution

  • I reported it as a minor bug in issue tracker : https://issuetracker.google.com/issues/238177355

    Update

    The issue is now fixed and you can find my solution here : https://github.com/alirezaeiii/Compose-CollapsingToolbar