안녕하세요. 이번 포스트에서는 Jetpack Compose Materail3를 활용해서 BottomNavigation을 구현하는 방법에 대해 알아보겠습니다!
1. Gradle 추가
implementation "androidx.compose.material3:material3:1.2.0-alpha02"
implementation "androidx.navigation:navigation-compose:2.6.0"
Compose에서 Navigation을 사용하기 위한 라이브러리를 추가해줍니다. 최신 버전은 각각의 공식문서에서 확인 하시면 됩니다.
2. BottomNavItem 선언
sealed class BottomNavItem(
val label: String,
val iconRes: Int,
val route: String,
) {
companion object {
private const val HOME_ROUTE = "HOME"
private const val SEARCH_ROUTE = "SEARCH"
private const val SHOP_ROUTE = "SHOP"
private const val SETTING_ROUTE = "SETTING"
}
object Home : BottomNavItem(
label = "Home",
iconRes = R.drawable.home,
route = HOME_ROUTE,
)
object Search : BottomNavItem(
label = "Search",
iconRes = R.drawable.search,
route = SEARCH_ROUTE,
)
object Shop : BottomNavItem(
label = "Shop",
iconRes = R.drawable.shop,
route = SHOP_ROUTE,
)
object Setting : BottomNavItem(
label = "Setting",
iconRes = R.drawable.settings,
route = SETTING_ROUTE,
)
}
BottomNavigation에서 사용할 오브젝트를 선언해줍니다.
label은 BottomBar에서 보여질 텍스트, route는 navigate에 사용됩니다.
3. BottomNavigationBar
@Composable
fun BottomNavigationBar(
navHostController: NavHostController,
) {
val bottomNavItems = remember {
listOf(
BottomNavItem.Home,
BottomNavItem.Search,
BottomNavItem.Shop,
BottomNavItem.Setting,
)
}
val navBackStackEntry by navHostController.currentBackStackEntryAsState()
val currentDestination = navBackStackEntry?.destination
NavigationBar {
bottomNavItems.forEach { item ->
NavigationBarItem(
icon = {
Icon(
modifier = Modifier.size(24.dp),
painter = painterResource(id = item.iconRes),
contentDescription = item.label,
)
},
label = {
Text(
text = item.label
)
},
alwaysShowLabel = true,
selected = currentDestination?.hierarchy?.any { it.route == item.route } == true,
onClick = {
navHostController.navigate(item.route) {
popUpTo(navHostController.graph.findStartDestination().id) {
saveState = true
}
launchSingleTop = true
restoreState = true
}
},
)
}
}
}
Materai3의 NavigationBar를 사용하여 BottmBar를 구현해줍니다. 인자로 받는 navHostController를 넘겨받는 부분은 다음에 나옵니다.
4. NavigationGraph
@Composable
fun NavigationGraph(
navHostController: NavHostController
) {
NavHost(
navController = navHostController,
startDestination = BottomNavItem.Home.route,
) {
composable(BottomNavItem.Home.route) {
HomeScreen()
}
composable(BottomNavItem.Search.route) {
SearchScreen()
}
composable(BottomNavItem.Shop.route) {
ShopScreen()
}
composable(BottomNavItem.Setting.route) {
SettingScreen()
}
}
}
NavigationGraph를 사용하여 각각의 route들이 가르키는 화면을 설정해줍니다.
5. 조합
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
val navHostController = rememberNavController()
Scaffold(
bottomBar = {
BottomNavigationBar(navHostController = navHostController)
}
) {
Surface(
modifier = Modifier.padding(it),
color = MaterialTheme.colorScheme.surface,
) {
NavigationGraph(navHostController = navHostController)
}
}
}
}
}
Scaffold bottomBar에 3번에서 구현한 BottomNavigationBar를 선언해줍니다.
끝!