0

How to create BottomNavigation with one of the item is larger than the parent, but without using floatingActionButton. For example like this:

enter image description here

I tried to do that by wrapping the icon with Box but it get cut like this:

enter image description here

Then i try to separate that one button and use constraintLayout to position it, but the constraintLayout cover the screen like this. Even when i color it using Color.Transparent, it always feels like Color.White (i dont know why Color.Transparent never work for me). In this picture i give it Red color for clarity reason.

enter image description here

So how to do this kind of bottomNavBar without having to create heavy-custom-composable?

Update: so i try to make the code based on MARSK and Dharman comment (thanks btw). This is what i

BoxWithConstraints(
    modifier = Modifier
        .fillMaxWidth()
        .wrapContentHeight()
        .background(Color.Transparent)
) {
    Box(
        modifier = Modifier
            .fillMaxWidth()
            .height(56.dp)
            .background(Color.White)
            .align(Alignment.BottomCenter)
    )
    Row(
        modifier = Modifier
            .zIndex(56.dp.value)
            .fillMaxWidth()
            .selectableGroup(),
        horizontalArrangement = Arrangement.SpaceBetween,
    ) {
        items.forEach { item ->
            val selected = item == currentSection

            BottomNavigationItem(
                modifier = Modifier
                    .align(Alignment.Bottom)
                    .then(
                        Modifier.height(
                            if (item == HomeSection.SCAN) 84.dp else 56.dp
                        )
                    ),
                selected = selected,
                icon = {
                    if (item == HomeSection.SCAN) {
                        ScanButton(navController = navController, visible = true)
                    } else {
                        ImageBottomBar(
                            icon = if (selected) item.iconOnSelected else item.icon,
                            description = stringResource(id = item.title)
                        )
                    }
                },
                label = {
                    Text(
                        text = stringResource(item.title),
                        color = if (selected) Color(0xFF361DC0) else LocalContentColor.current.copy(
                            alpha = LocalContentAlpha.current
                        ),
                        style = TextStyle(
                            fontFamily = RavierFont,
                            fontWeight = if (selected) FontWeight.Bold else FontWeight.Normal,
                            fontSize = 12.sp,
                            lineHeight = 18.sp,
                        ),
                        maxLines = 1,
                    )
                },
                onClick = {
                    if (item.route != currentRoute && item != HomeSection.SCAN) {
                        navController.navigate(item.route) {
                            launchSingleTop = true
                            restoreState = true
                            popUpTo(findStartDestination(navController.graph).id) {
                                saveState = true
                            }
                        }
                    }
                }
            )
        }
    }
}

It works in preview, but doesn't work when i try in app. This one in the preview, the transparent working as expected:

enter image description here

And this is when i try to launch it, the transparent doesnt work:

enter image description here

Note: I assign that to bottomBar of Scaffold so i could access the navigation component. Is it the cause that Transparent Color doesnt work?

Update 2: so the inner paddingValues that makes the transparent doesnt work. I fixed it by set the padding bottom manually:

PaddingValues(
    start = paddingValues.calculateStartPadding(
        layoutDirection = LayoutDirection.Ltr
    ),
    end = paddingValues.calculateEndPadding(
        layoutDirection = LayoutDirection.Ltr
    ),
    top = paddingValues.calculateTopPadding(),
    bottom = SPACE_X7,
)

1 Answer 1

2

Custom Composable are not heavy, really.

Anyway, try this:-

Create a Container of MaxWidth (maybe a BoxWithConstraints or something), keep its background transparent, set the height to wrap content. Create the tabs as usual, but keeping the bigger tab's icon size bigger explicitly using Modifier.size(Bigger Size).

After you have this setup, add another container inside this container with white background, covering a specific height of the original container. Let's say 60%

Now set the z-index of all the icons and tabs to higher than the z-index of this lastly added container. Use Modifier.zIndex for this. And viola, you have your Composable ready.

In order to set a specific percentage height of the inner container, you will need access to the height of the original container. Use BoxWithConstraints for that, or just implement a simple custom Layout Composable

Sign up to request clarification or add additional context in comments.

4 Comments

Hi sir, thanks for the help. It kinda works but i got some weird(?) height. I use the BottomNavigationItem for the tabs. So the hierarchy would be: BoxWithConstraint (set height to wrap content) -> Row (because BottomNavItem need Rowscope) -> BottomNavigationItem (as the tabs). And the weird height is come from BottomNavigationItem, if i dont specify its height, it behaves like fillMaxHeight. Why does this happen?
*i edit the post to add the update of the code i made based on your suggestion with the screenshot
It could be because of adding it in the scaffold's parameter-based nav system. Also, sometimes I think the Color. Transparent call not working can be fixed by setting the Alpha to zero (or near zero) as well. Try that. Maybe it works.
Yes true, it is because the bottomBar scaffold. But i have solved that yesterday. Thanks for the help.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.