androidandroid-jetpack-compose

Jetpack Compose: Transparent "fade" gradient in BottomBar


I want to add faded bottombar background to my custom NavigationBar I made.

It is accepting Transparent color and solid color but if I want to place there verticalGradient, it returns only solid color. This behavior is not happening if I use it in any other component such as Box.

It might be bug with Scaffold component but I'm not sure.

What I want to achieve is basically that I have verticalScroll inside my content in Scaffold and if I scroll down and content is going behind buttomBar, it is clipped by its background which suppose to be transparent at the top and slowly fade to solid color (thats why I want to wrap it with Box with verticalGradient). If I set that Box to Transparent, it is transparent and its not clipping my content, but gradient is for some reason not supported. It transforms into solid color no matter what startY/endY I set there.

I'm using this technique with verticalGradient in Screen background components where bottom component has faded edge and its working without any issues. It's just if its used in Scaffold bottomBar it is ignored.

val backgroundColor = Brush.verticalGradient(
        colors = listOf(
            Color.Transparent,
            tabColors.backgroundBottom,
        ),
        startY = 0f,
        endY = 50f,
        tileMode = TileMode.Clamp,
    )

Scaffold (
        bottomBar = {
            if (isTabBarVisible) {
                Box(
                    modifier = Modifier
                        .fillMaxWidth()
                        .background(backgroundColor)
                        .padding(16.dp)
                ) {
                    TabBar(
                        navController = navController,
                    )
                }
            }
        }
    ) { innerPadding ->
        NavHost(
            modifier = Modifier.padding(innerPadding),
            navController = navController,
            startDestination = Screen.SplashData,
        ) {
            ... navigation to screens
        }
    }

Here is visual representation what I want to achieve.

White == Transparent

Scrollable Content == Content displayed by NavHost (Composable Screens with lifecycle)

"Fade" Background should be part of the TabBar because there is Content (screens) where Navigation bottom bar is hidden and I dont want to have fade there.

enter image description here

This is how it looks now if I pass there verticalGradient (it takes non-transparent color as solid one) which is causing clipping of scrollable content behind tab bar (bottom bar).

enter image description here


Solution

  • Adjusting a new padding value from the inner padding of the Scaffold and setting the bottom to zero may be sufficient to solve the problem. This way, you won't have to worry about the Snackbar.

    Scaffold(
        snackbarHost = { SnackbarHost(snackbarHostState) },
        bottomBar = {
           // ur bottom bar
        }
    ) { innerPadding ->
    
        val paddingValues = PaddingValues(
            start = innerPadding.calculateStartPadding(LocalLayoutDirection.current),
            top = innerPadding.calculateTopPadding(),
            end = innerPadding.calculateEndPadding(LocalLayoutDirection.current),
            bottom = 0.dp
        )
    
        NavHost(
            modifier = Modifier
                .padding(paddingValues),
            navController = navController,
            startDestination = Screen.SplashData,
        ) {
            ... navigation to screens
        } 
    }