본문 바로가기

안드로이드/Compose UI

[안드로이드 Jetpack Compose UI] TabPager 구현하기


안녕하세요. 이번 포스팅에서는 안드로이드 Jetpack Compose에서 TabPager를 구현하겠습니다. TabPager는 상당히 많이 사용되는 UI 중 하나입니다. TabPager를 구현할 때는 ViewPager를 연동해서 사용해야 하는데, 기존 xml 방식으로 UI를 개발할 때는 Adapter 클래스를 생성해야만 했고 연동 과정이 복잡했습니다. 그런데 안드로이드 Compose에서는 이러한 복잡한 과정이 사라졌으며 비교적 간단하게 TabPager를 구현할 수 있습니다. 이제 안드로이드 Jetpack Compose에서 TabPager를 구현하는 방법에 대해 설명하겠습니다.

안드로이드 Jetpack Compose에서 구현한 TabPager
안드로이드 Jetpack Compose에서 구현한 TabPager

1. TabPager 만들기

TabPager를 구현하기 위해 먼저 TabRow와 HorizontalPager를 연동하는 작업이 필요합니다. ScrollableTabRow는 탭을 표시하고, HorizontalPager는 각 탭에 해당하는 페이지를 보여줍니다. 먼저, ScrollableTabRow 내부에 Tab 컴포저블을 사용하여 탭들을 만들고, 사용자가 탭을 선택할 때마다 HorizontalPager의 페이지가 변경되도록 설정합니다. HorizontalPager의 상태는 rememberPagerState()를 사용하여 관리합니다.

@Composable
fun CustomTabPager(pagerState: PagerState, tabs: List<String>) {

    val coroutineScope = rememberCoroutineScope() // 코루틴 스코프 생성

    Column {
        // 탭 구현
        ScrollableTabRow(
            selectedTabIndex = pagerState.currentPage,
            indicator = { tabPositions ->
                TabRowDefaults.SecondaryIndicator(
                    modifier = Modifier.tabIndicatorOffset(tabPositions[pagerState.currentPage]),
                    color = Color.Red, // 인디케이터 색상 변경
                )
            },
            divider = {}, // 빈 컴포저블을 지정하여 경계선 제거
            containerColor = Color.White, // 배경색 설정
            contentColor = Color.Red,
            edgePadding = 0.dp, // 패딩 설정
        ) {
            tabs.forEachIndexed { index, title ->
                Tab(
                    text = { Text(title) },
                    selected = pagerState.currentPage == index,
                    modifier = Modifier
                        .width(100.dp)  // 탭의 가로 크기
                        .height(50.dp), // 탭의 세로 크기
                    onClick = {
                        coroutineScope.launch {
                            pagerState.animateScrollToPage(index)
                        }
                    }
                )
            }
        }
        HorizontalDivider(
            modifier = Modifier
                .fillMaxWidth(), // 화면 전체 너비
            color = Color.LightGray, // 테두리 색상
            thickness = 1.dp // 테두리 두께
        )

        // 뷰페이저 구현
        HorizontalPager(
            state = pagerState
        ) { page ->
            Column(
                modifier = Modifier
                    .fillMaxSize()
                    .background(Color.White),
                verticalArrangement = Arrangement.Center,
                horizontalAlignment = Alignment.CenterHorizontally
            ) {
                // 페이지별 컨텐츠
                when (page) {
                    0 -> HomeScreen()
                    1 -> SettingsScreen()
                    2 -> ProfileScreen()
                }
            }
        }
    }
}


TabPager를 사용할 때는 탭과 페이지 간의 상태를 동기화해야 합니다. 이를 위해 HorizontalPager의 currentPage 상태를 ScrollableTabRow의 selectedTabIndex에 연결합니다. 사용자가 탭을 클릭하면 HorizontalPager의 현재 페이지가 변경되도록 설정하고, 페이지를 슬라이드 할 때 해당하는 탭이 강조되도록 연동합니다.

2. TabPager 사용하기

위에서 만든 TabPager를 사용하는 방법은 간단합니다. TabPager를 사용하고자 하는 컴포저블 함수에서 CustomTabPager를 생성하고, 매개변수로 PagerState와 tab을 구성하는 tabs 배열을 전달하면 됩니다. PagerState는 rememberPagerState를 통해 생성할 수 있습니다.

@Composable
fun TabPagerScreen(
    mainNavController: NavHostController,
    viewModel: TabPagerViewModel
) {
    val tabs = listOf("홈", "설정", "프로필")
    val pagerState = rememberPagerState {
        tabs.size
    }

    Column {
        CustomTabPager(
            pagerState = pagerState,
            tabs = tabs
        )
    }
}

3. 안드로이드 Jetpack Compose TabPager 정리

안드로이드 Jetpack Compose를 이용한 TabPager 구현은 기존의 복잡한 구현 방식에 비해 훨씬 간결하고 직관적입니다. TabRow와 HorizontalPager를 적절히 연동하면, 사용자에게 매끄러운 탐색 경험을 제공하는 TabPager를 쉽게 만들 수 있습니다.

이 포스팅을 통해 Jetpack Compose를 이용한 TabPager 구현 방법을 간략히 소개했습니다. 해당 예제에서는 탭의 크기, 인디케이터 색상, 하단 구분선 등 UI를 커스텀할 수 있는 요소도 구현했습니다. 안드로이드 Jetpack Compose를 활용한 다양한 UI 구현 방법을 알고 싶은 분들에게 이 포스팅이 도움이 되길 바랍니다.