[Android / Kotlin] Compose에서 NavigationBar를 활용한 하단 Tab 구현

2024. 10. 1. 22:11· Development/Android
반응형

컴포즈에서 하단에 4칸짜리 탭을 구현해 보겠습니다.

먼저 gradle에 아래 navigation 의존성 추가가 필요합니다.

implementation("androidx.navigation:navigation-compose:2.8.1")
implementation("androidx.compose.material3:material3:1.2.1")

 

탭을 구성하기 위해서는 NavigationBar, NavigationGraph, 각 탭 별 Screen Class가 필요합니다.

그리고 화면에서 NavController를 통해 등록된 화면 간의 이동을 제어하게 됩니다.

 

먼저 필요한 화면에 대한 기본 데이터(route, title, icon....)들을 sealed class로 정의해 줍니다.

sealed class Screen(val route: String, val title: String, val icon: ImageVector) {
    data object Home : Screen("home", "Home", Icons.Default.Home)
    data object Notes : Screen("notes", "Notes", Icons.Default.Search)
    data object Daily : Screen("daily", "Daily", Icons.Default.Check)
    data object Settings : Screen("settings", "Settings", Icons.Default.Settings)
}

 

그리고 sealed class가 선언된 해당 파일에서 NavigationBar, NavigationGraph도 마저 구성해 줍니다.

@Composable
fun BottomNavBar(navController: NavController) {
    val items = listOf(
        Screen.Home,
        Screen.Notes,
        Screen.Daily,
        Screen.Settings
    )

    NavigationBar {
        val navBackStackEntry by navController.currentBackStackEntryAsState()
        val currentRoute = navBackStackEntry?.destination?.route

        items.forEach { screen ->
            NavigationBarItem(
                icon = {
                    Icon(
                        imageVector = screen.icon,
                        contentDescription = screen.title
                    )
                },
                label = { Text(screen.title) },
                selected = currentRoute == screen.route,
                onClick = {
                    navController.navigate(screen.route) {
                        popUpTo(navController.graph.startDestinationId) { saveState = true }
                        launchSingleTop = true
                        restoreState = true
                    }
                }
            )
        }
    }
}

각 NavigationBarItem을 클릭하면 controller는 선택된 screen의 고유 id 값인 route를 통해 탭을 전환하게 됩니다.

 

@Composable
fun NavigationGraph(
    navController: NavHostController,
    dataViewModel: DataViewModel,
    paddingValues: PaddingValues) {
    NavHost(navController, startDestination = Screen.Home.route) {
        composable(Screen.Home.route) { HomeScreen(dataViewModel, paddingValues) }
        composable(Screen.Notes.route) { NotesScreen() }
        composable(Screen.Daily.route) { DailyScreen() }
        composable(Screen.Settings.route) { SettingsScreen() }
    }
}

NavGraph에서는 실제로 필요한 화면 컴포저블을 NavHost에 등록합니다. 
NavHost는 Controller가 작동할 때, route에 따라 화면 전환을 제공하게 됩니다.

 

@Composable
fun HomeScreen(viewModel: DataViewModel, paddingValues: PaddingValues) {
    Box(
        modifier = Modifier
            .fillMaxSize()
            .padding(paddingValues),
        contentAlignment = Alignment.Center
    ) {
        MindBankTheme {
            Surface(
                modifier = Modifier.fillMaxSize(),
                color = MaterialTheme.colorScheme.background
            ) {
                MainScreen(viewModel)
            }
        }
    }
}

@Composable
fun NotesScreen() {
    Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
        Text("Notes Screen")
    }
}

....

Screen 화면을 목적에 맞게 구성해 줍니다.

참고로 paddingValues를 인자로 넘겨받으면 하단 탭 높이만큼의 padding을 각 화면에 전달하여 컴포넌트가 가려지지 않도록 할 수 있습니다!

 

이제 Navigation을 적용해 줄 Activity에 아래와 같이 구성하면 완료입니다.

@AndroidEntryPoint
class MainActivity : ComponentActivity() {

    private val dataViewModel: DataViewModel by viewModels()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            val navController = rememberNavController()

            Scaffold(
                bottomBar = { BottomNavBar(navController = navController) }
            ) { paddingValues ->
                NavigationGraph(navController, dataViewModel, paddingValues)
            }
        }
    }
}

반응형
저작자표시 (새창열림)
'Development/Android' 카테고리의 다른 글
  • [Android] 디자인 시스템 및 컴포즈 기본 도입에 관한 발표 자료
  • [Android / Compose] 컴포넌트 onClick으로 Navigation 탭 변경 처리
  • [Android] SQLite 순차적 DB Query 작업의 우선처리 개선
  • [Android] RecyclerView 최상단 또는 최하단에 여백 넣기
SeungYong.Lee
SeungYong.Lee
반응형
SeungYong.Lee
Win-Dev
SeungYong.Lee
전체
오늘
어제
  • All (239)
    • Development (139)
      • Android (135)
      • iOS (0)
      • Flutter (4)
      • Backend (0)
    • Algorithm (5)
    • Knowledge (5)
      • IT (2)
      • Science (0)
      • ETC & Tip (3)
    • Today I Learn (28)
    • Coding Test (62)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

  • 안녕하세요. 반갑습니다 :)

인기 글

태그

  • Android
  • 코틀린
  • Animation
  • hilt
  • bitmap
  • Flutter
  • exception
  • 비동기처리
  • 코딩테스트
  • 프로그래머스
  • HTTP
  • glance
  • Java
  • coroutine
  • dfs
  • compose
  • Retrofit
  • Kotlin
  • Widget
  • Collection

최근 댓글

최근 글

hELLO · Designed By 정상우.v4.2.2
SeungYong.Lee
[Android / Kotlin] Compose에서 NavigationBar를 활용한 하단 Tab 구현
상단으로

티스토리툴바

개인정보

  • 티스토리 홈
  • 포럼
  • 로그인

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.