How to create bottom navigation with Jetpack compose?

Last updated Dec 08, 2021


In this Jetpack compose tutorial we will learn How to create bottom navigation in Android application using Jetpack Compose. 

Bottom navigation allow user to switch between different screen very easily.

To create a bottom navigation we are going to use Scaffold. Scaffold basically provides API that will combine different material components to make our layout.

Let's get started

Step 1: Create android application in android studio

Step 2: Follow step for setup Jetpack Compose with Android Studio

Lets add simple example of Scaffold with bottom app bar

JetPackTheme(
    darkTheme = true,
) {
    Scaffold(
        modifier = Modifier.fillMaxSize(),
        content = {
            //here we are going to show each screen layout
        },
        bottomBar = {       
           //here we are going to add bottom app bar
        }
    )
}

 

 

We are going to display 3 menu basically Home, Contacts and Settings

val bottomNavigationScreens = listOf(
    BottomNavigationBarScreen.Home,
    BottomNavigationBarScreen.Contact,
    BottomNavigationBarScreen.Settings
)

 

 

Lets create a sealed class (where Sealed class is basically restricted class hierarchies which gives more control over inheritance)

which will contain route,title ,icon and screen to load on selecting particular menu.

sealed class BottomNavigationBarScreen(
    val route: String,
    val title: String,
    val screenToLoad: @Composable () -> Unit,
    val icon: ImageVector
) {
    object Home : BottomNavigationBarScreen("home", "Home", {
        HomeScreenForBottomNavigationBar()
    }, Icons.Default.Home)

    object Settings : BottomNavigationBarScreen("settings", "Settings", {
        SettingsScreenForBottomNavigationBar()
    }, Icons.Default.Settings)

    object Contact : BottomNavigationBarScreen("contacts", "Contacts", {
        ContactScreenForBottomNavigationBar()
    }, Icons.Default.Contacts)
}

 

 

Let's create 3 screens

Home Screen

@Composable
fun HomeScreenForBottomNavigationBar() {
    Column(
        content = {
            Spacer(modifier = Modifier.padding(20.dp))
            Row() {
                Box(
                    content = {
                        Text(
                            text = "H",
                            fontSize = 24.sp,
                            color = Color.Red
                        )
                    }, modifier = Modifier
                        .padding(start = 16.dp)
                        .size(80.dp)
                        .border(width = 6.dp, color = Color.Red, shape = CircleShape),
                    contentAlignment = Alignment.Center
                )
                Box(
                    content = {
                        Text(
                            text = "O",
                            fontSize = 24.sp,
                            color = Color.Red
                        )
                    }, modifier = Modifier
                        .padding(start = 16.dp)
                        .size(80.dp)
                        .border(width = 6.dp, color = Color.Blue, shape = CircleShape),
                    contentAlignment = Alignment.Center
                )
                Box(
                    content = {
                        Text(
                            text = "M",
                            fontSize = 24.sp,
                            color = Color.Red
                        )
                    }, modifier = Modifier
                        .padding(start = 16.dp)
                        .size(80.dp)
                        .border(width = 6.dp, color = Color.Red, shape = CircleShape),
                    contentAlignment = Alignment.Center
                )
                Box(
                    content = {
                        Text(
                            text = "E",
                            fontSize = 24.sp,
                            color = Color.Red
                        )
                    }, modifier = Modifier
                        .padding(start = 16.dp)
                        .size(80.dp)
                        .border(width = 6.dp, color = Color.Blue, shape = CircleShape),
                    contentAlignment = Alignment.Center
                )
            }
            Box(
                content = {
                }, modifier = Modifier
                    .padding(16.dp)
                    .fillMaxWidth()
                    .height(16.dp)
                    .background(color = Color.Red)
            )
            Box(
                content = {
                }, modifier = Modifier
                    .padding(16.dp)
                    .fillMaxWidth()
                    .height(16.dp)
                    .background(color = Color.Blue)
            )
            Row(horizontalArrangement = Arrangement.Center, modifier = Modifier.fillMaxWidth()) {
                Box(
                    content = {
                    }, modifier = Modifier
                        .padding(start = 16.dp)
                        .size(100.dp)
                        .background(color = Color.Red)
                        .border(width = 0.dp, color = Color.Red, shape = RectangleShape),
                    contentAlignment = Alignment.Center
                )
                Box(
                    content = {
                    }, modifier = Modifier
                        .padding(start = 16.dp)
                        .size(100.dp)
                        .background(color = Color.Blue)
                        .border(width = 0.dp, color = Color.Blue, shape = RectangleShape),
                    contentAlignment = Alignment.Center
                )
            }

            Box(
                content = {
                }, modifier = Modifier
                    .padding(16.dp)
                    .fillMaxWidth()
                    .height(16.dp)
                    .background(color = Color.Red)
            )
            Box(
                content = {
                }, modifier = Modifier
                    .padding(16.dp)
                    .fillMaxWidth()
                    .height(16.dp)
                    .background(color = Color.Blue)
            )

            Row(horizontalArrangement = Arrangement.Center, modifier = Modifier.fillMaxWidth()) {
                Box(
                    content = {
                        Icon(Icons.Default.Home, "", tint = Color.Red)
                    }, modifier = Modifier
                        .padding(start = 16.dp)
                        .size(100.dp)
                        .border(width = 6.dp, color = Color.Blue, shape = CircleShape),
                    contentAlignment = Alignment.Center
                )
                Box(
                    content = {
                        Icon(Icons.Default.Hail, "", tint = Color.Blue)
                    }, modifier = Modifier
                        .padding(start = 16.dp)
                        .size(100.dp)
                        .border(width = 6.dp, color = Color.Red, shape = CircleShape),
                    contentAlignment = Alignment.Center
                )
                Box(
                    content = {
                        Icon(Icons.Default.Hardware, "", tint = Color.Red)
                    }, modifier = Modifier
                        .padding(start = 16.dp)
                        .size(100.dp)
                        .border(width = 6.dp, color = Color.Blue, shape = CircleShape),
                    contentAlignment = Alignment.Center
                )
            }
            Box(
                content = {
                    Row(content = {
                        Icon(
                            Icons.Default.Pages, "", tint = Color.Red, modifier = Modifier
                                .padding(start = 16.dp)
                        )
                        Icon(
                            Icons.Default.Palette, "", tint = Color.Red, modifier = Modifier
                                .padding(start = 16.dp)
                        )
                        Icon(
                            Icons.Default.PanoramaFishEye, "", tint = Color.Red, modifier = Modifier
                                .padding(start = 16.dp)
                        )
                        Icon(
                            Icons.Default.PanoramaWideAngleSelect,
                            "",
                            tint = Color.Red,
                            modifier = Modifier
                                .padding(start = 16.dp)
                        )
                    })
                }, modifier = Modifier
                    .padding(16.dp)
                    .height(80.dp)
                    .fillMaxWidth()
                    .background(color = Color.Blue),
                contentAlignment = Alignment.Center
            )
        }, modifier = Modifier
            .fillMaxSize()
    )
}

 

 

Contacts Screen

data class Contact(val id: String, val name: String, val emailId: String)
@Composable
fun ContactScreenForBottomNavigationBar() {
    val contacts = listOf(
        Contact(id = "1", name = "Ankit Singh", emailId = "abc@gmail.com"),
        Contact(id = "2", name = "Rishabh Shaw", emailId = "xyz@gmail.com"),
        Contact(id = "3", name = "Neha Shaw", emailId = "abc@gmail.com"),
        Contact(id = "4", name = "Ekta Gupta", emailId = "xyz@gmail.com"),
        Contact(id = "5", name = "Rahul Jaiswal", emailId = "abc@gmail.com"),
        Contact(id = "6", name = "Anindita Chatterjee", emailId = "xyz@gmail.com"),
        Contact(id = "7", name = "Aakash Raj", emailId = "abc@gmail.com"),
        Contact(id = "8", name = "Arpita Ghosh", emailId = "xyz@gmail.com"),
        Contact(id = "9", name = "Arvind Patel", emailId = "abc@gmail.com"),
        Contact(id = "10", name = "Akash Tiwari", emailId = "xyz@gmail.com")
    )
    Scaffold(
        content = {
            LazyColumn(
                contentPadding = PaddingValues(
                    bottom = 100.dp,
                    start = 16.dp,
                    end = 16.dp
                )
            ) {
                items(
                    items = contacts,
                    itemContent = {
                        ContactListItem(contact = it)
                    })
            }
        },
        topBar = {
            TopAppBar(
                title = { Text("Contacts") },
                backgroundColor = Color.White,
                contentColor = Color.Blue
            )
        },
    )
}


@Composable
fun ContactListItem(contact: Contact) {
    Card(
        modifier = Modifier
            .padding(top = 16.dp)
            .fillMaxWidth(),
        elevation = 4.dp,
        border = BorderStroke(width = 1.2.dp, Color.Blue)
    ) {
        Row(content = {
            Icon(
                Icons.Default.Contacts,
                "",
                tint = Color.Blue,
                modifier = Modifier
                    .padding(start = 16.dp, top = 16.dp)
            )
            Column(modifier = Modifier.padding(16.dp)) {
                Text(
                    text = contact.name,
                    style = TextStyle(
                        color = Color.Blue,
                        fontSize = 21.sp,
                        fontWeight = FontWeight.Bold
                    )
                )
                Text(text = contact.emailId, modifier = Modifier.padding(top = 8.dp))
            }
        })

    }

}

 

 

Settings Screen

data class Setting(val title: String)

@Composable
fun SettingsScreenForBottomNavigationBar() {
    val settings = listOf(
        Setting(title = "Account"),
        Setting(title = "Notification"),
        Setting(title = "Appearance"),
        Setting(title = "Privacy & Setting"),
        Setting(title = "Help & Support"),
        Setting(title = "About")
    )
    Scaffold(
        content = {
            LazyColumn(
                contentPadding = PaddingValues(
                    bottom = 100.dp,
                    start = 16.dp,
                    end = 16.dp
                )
            ) {
                items(
                    items = settings,
                    itemContent = {
                        SettingListItem(setting = it)
                    })
            }
        },
        topBar = {
            TopAppBar(
                title = { Text("Settings") },
                backgroundColor = Color.White,
                contentColor = Color.Blue
            )
        },
    )
}

@Composable
fun SettingListItem(setting: Setting) {
    Column() {
        Spacer(modifier = Modifier.padding(16.dp))
        Row(content = {
            Icon(
                Icons.Default.Settings,
                "",
                tint = Color.Red,
                modifier = Modifier
                    .padding(start = 16.dp)
            )
            Text(
                text = setting.title,
                style = TextStyle(
                    color = Color.Blue,
                    fontSize = 21.sp,
                    fontWeight = FontWeight.Bold
                ), modifier = Modifier
                    .padding(start = 16.dp)
            )
        }, modifier = Modifier.fillMaxWidth())
        Spacer(modifier = Modifier.padding(16.dp))
        Spacer(
            modifier = Modifier
                .height(height = 1.2.dp)
                .fillMaxWidth()
                .background(color = Color.Gray)
        )

    }

}

 

 

Add Bottom Navigation Code

@Composable
fun BottomNavigationDemo() {
    val currentScreen =
        remember { mutableStateOf(BottomNavigationBarScreen.Home) }

    JetPackTheme(
    ) {
        Scaffold(
            modifier = Modifier.fillMaxSize(),
            content = {
                currentScreen.value.screenToLoad()
            },
            bottomBar = {
                BottomNavigation(content = {
                    bottomNavigationScreens.forEach { bottomNavigationBarScreen: BottomNavigationBarScreen ->
                        BottomNavigationItem(
                            selected = currentScreen.value.route == bottomNavigationBarScreen.route,
                            label = {
                                Text(text = bottomNavigationBarScreen.title)
                            },
                            onClick = {
                                currentScreen.value = bottomNavigationBarScreen
                            },
                            icon = {
                                Icon(bottomNavigationBarScreen.icon, "")
                            },
                            selectedContentColor = Color.Red,
                            unselectedContentColor = Color.Gray
                        )
                    }
                }, backgroundColor = Color.White)
            }
        )
    }
}

 

 

Call BottomNavigationDemo() function from MainActivity.kt

 

package com.example.jetpack

import android.os.Bundle
import android.view.WindowManager
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.runtime.*
import androidx.compose.ui.tooling.preview.Preview
import com.example.jetpack.widget.BottomNavigationDemo

class MainActivity : ComponentActivity() {

    @ExperimentalFoundationApi
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE)
        setContent {
            BottomNavigationDemo()
        }
    }
}

 

 

 

Images

Jetpack compose Bottom Navigationvbar


Article Contributed By :
https://www.rrtutors.com/site_assets/profile/assets/img/avataaars.svg

445 Views

Subscribe For Daily Updates

Flutter Questions
Android Questions