androidandroid-jetpack-compose

Collapse Navigation BottomBar while scrolling on Jetpack Compose


I'm looking forward to a way to implement a Collapsing effect while scrolling on LazyColumn list. I have been checking the docs but I didn't found nothing related. How can I implement it?

At the moment I'm using a BottomNavigation setted inside my Scaffold and I can add the inner paddings to the screen coming from the scaffold content lambda. But I didn't find any kind of scrollable state or something close to it.


Solution

  • You can use the nestedScroll modifier.

    Something like:

    val bottomBarHeight = 48.dp
    val bottomBarHeightPx = with(LocalDensity.current) { bottomBarHeight.roundToPx().toFloat() }
    val bottomBarOffsetHeightPx = remember { mutableStateOf(0f) }
    
    
    // connection to the nested scroll system and listen to the scroll
    // happening inside child LazyColumn
    val nestedScrollConnection = remember {
        object : NestedScrollConnection {
            override fun onPreScroll(available: Offset, source: NestedScrollSource): Offset {
    
                val delta = available.y
                val newOffset = bottomBarOffsetHeightPx.value + delta
                bottomBarOffsetHeightPx.value = newOffset.coerceIn(-bottomBarHeightPx, 0f)
    
                return Offset.Zero
            }
        }
    }
    

    and then apply the nestedScroll to the Scaffold:

    Scaffold(
        Modifier.nestedScroll(nestedScrollConnection),
        scaffoldState = scaffoldState,
        //..
        bottomBar = {
            BottomAppBar(modifier = Modifier
                .height(bottomBarHeight)
                .offset { IntOffset(x = 0, y = -bottomBarOffsetHeightPx.value.roundToInt()) }) {
                IconButton(
                    onClick = {
                        coroutineScope.launch { scaffoldState.drawerState.open() }
                    }
                ) {
                    Icon(Icons.Filled.Menu, contentDescription = "Localized description")
                }
            }
        },
    
        content = { innerPadding ->
            LazyColumn(contentPadding = innerPadding) {
                items(count = 100) {
                    Box(
                        Modifier
                            .fillMaxWidth()
                            .height(50.dp)
                            .background(colors[it % colors.size])
                    )
                }
            }
        }
    )
    

    enter image description here