본문 바로가기

안드로이드/Compose UI

[안드로이드 Jetpack Compose UI 시리즈] ViewPager 구현하기


728x90

안녕하세요. 이번 포스팅에서는 안드로이드 Jetpack Compose에서 ViewPager를 구현하겠습니다. ViewPager는 최근 앱에서 많이 사용되고 있는 대표적인 UI 중 하나입니다. 기존 xml에서는 ViewPager를 구현하기 위해 별도의 Adapter를 생성하고, item에 해당되는 xml도 생성해줘야 했습니다. 그런데 안드로이드 Jetpack Compose에서는 상당히 편하게 구현할 수 있습니다. 이제 안드로이드 Jetpack Compose에서 ViewPager를 구현하겠습니다.

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

1. ViewPager 만들기

좌우로 넘어가는 ViewPager를 만들기 위해서 androidx.compose.foundation.pager의 HorizontalPager를 사용했습니다. 만약에 위아래로 넘길 수 있는 ViewPager를 만들려면 VerticalPager를 사용하면 됩니다. HorizontalPager는 state만 제공하면 사용할 수 있는데, rememberPagerState를 사용해서 페이저 상태 홀더 객체를 얻을 수 있습니다.

rememberPagerState 함수를 사용하여 생성된 PagerState는 현재 페이지의 인덱스, 스와이프 상태 등을 관리합니다. 이 상태는 CustomViewPager의 호출자에 의해 생성되고 관리되게 구현했습니다. 각 페이지는 Card 컴포저블로 렌더링 되며, Column을 사용해서 카드 내부의 Text 컴포저블을 가운데에 정렬되게 했습니다. 아래는 예시 코드입니다.

@Composable
fun CustomViewPager(pagerState: PagerState) {
    HorizontalPager(
        modifier = Modifier.fillMaxSize(),
        verticalAlignment = Alignment.CenterVertically,

        state = pagerState
    ) {
        Card(
            modifier = Modifier
                .fillMaxWidth()
                .height(100.dp)
                .padding(horizontal = 20.dp),
            shape = RoundedCornerShape(8.dp),
            border = BorderStroke(1.dp, Color.Black),
            colors = CardDefaults.cardColors(
                containerColor = Color.White,
            ),
            elevation = CardDefaults.cardElevation(10.dp),
        ) {
            Column(
                modifier = Modifier.fillMaxSize(),
                verticalArrangement = Arrangement.Center, // 세로 방향으로 가운데 정렬
                horizontalAlignment = Alignment.CenterHorizontally // 가로 방향으로 가운데 정렬
            ) {
                Text(
                    text = "Page $it",
                )
            }
        }
    }
}


CustomViewPager 컴포저블 함수를 만들었습니다. 재사용성을 높이기 위해서 PagerState를 CustomViewPager 호출자로부터 전달받도록 상태 호이스팅 패턴을 이용했습니다. 상태 호이스팅 패턴을 이용한 이유는 CustomViewPager 컴포저블이 더 유연하고 재사용이 가능해지기 때문입니다.

상태 호이스팅이란, 컴포저블 함수 자체가 상태를 가지지 않고 부모 컴포저블로부터 전달받아 사용하는 패턴입니다.

2. ViewPager 사용하기

위에서 만든 ViewPager를 사용하는 방법은 엄청 간단합니다. 이번 예제에서는 ViewPagerScreen 컴포저블에서 CustomViewPager 컴포저블을 호출해서 ViewPager를 사용합니다. 이때, rememberPagerState로 생성한 pagerState를 CustomViewPager에 전달해서 페이지 상태를 관리합니다.

@Composable
fun ViewPagerScreen(
    mainNavController: NavHostController,
    viewModel: ViewPagerViewModel
) {

    val pagerState = rememberPagerState {
        10 // 총 페이지 수 설정
    }

    Column(
        modifier = Modifier
            .fillMaxSize()
            .padding(10.dp)
    ) {
        Text(
            text = "Hello Android Compose ViewPager"
        )

        Spacer(modifier = Modifier.height(20.dp))

		// 현재 페이지 수와 현재 페이지 인덱스를 보여줌
        Text(
            text = "pageCount : ${pagerState.pageCount}"
        )
        Text(
            text = "currentPage : ${pagerState.currentPage}"
        )

        Spacer(modifier = Modifier.height(20.dp))

		// CustomViewPager에 pagerState를 전달
        CustomViewPager(pagerState = pagerState)
    }
}

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

이번 포스팅에서는 안드로이드 Jetpack Compose를 사용하여 ViewPager를 구현하는 방법을 살펴보았습니다. rememberPagerState를 사용하여 PagerState를 관리하고, HorizontalPager를 통해 페이지 스크롤을 구현할 수 있습니다. 이번 예제에서는 CustomViewPager 컴포저블 함수를 사용하여 더 유연하고 재사용 가능한 구조를 만들었습니다. 상태 호이스팅 패턴을 사용하여 컴포저블의 상태를 상위 컴포저블로부터 전달받도록 했습니다. 이를 통해 컴포저블의 재사용성을 높이고, 다른 컴포저블과의 결합을 최소화할 수 있었습니다.

이러한 방식으로 Jetpack Compose에서 ViewPager를 구현함으로써, 사용자에게 매력적인 스크롤 가능한 화면을 제공하면서도 유지보수와 확장성을 향상할 수 있고, 전통적인 xml 기반 개발에서의 복잡한 Adapter 설정과는 달리 Compose에서는 상대적으로 간단하고 직관적인 방식으로 구현할 수 있습니다.