[Compose UI] Pager

LeeEunJae·2022년 12월 26일
0
post-custom-banner

📌 결과 화면

오늘은 Jetpack Compose에서 Pager를 사용하는 방법에 대해서 알아보겠습니다.

📌 개발 환경 세팅

accompanist pager 공식문서
accompanist pager 라는 라이브러리를 사용할겁니다.

repositories {
    mavenCentral()
}

dependencies {
    implementation "com.google.accompanist:accompanist-pager:<version>"

    // If using indicators, also depend on 
    implementation "com.google.accompanist:accompanist-pager-indicators:<version>"
}

release 버전은 아래 사이트를 통해 확인해주세요
accompanist pager github

📌 Pager + 버튼 조작 + indicator

@OptIn(ExperimentalPagerApi::class)
@Composable
fun MyPager(){
    val pagerState = rememberPagerState()
    val coroutineScope = rememberCoroutineScope()

    Column() {
        Row(
            Modifier.fillMaxWidth(),
            horizontalArrangement = Arrangement.SpaceBetween
        ) {
            Button(
                onClick = {
                    coroutineScope.launch {
                        if(pagerState.currentPage <= 0) return@launch
                        // animateScrollToPage 함수는 suspend function 이기 때문에 Coroutine scope 내에서 호출해야 함
                        pagerState.animateScrollToPage(pagerState.currentPage - 1)
                    }
                },

            ) {
               Text(text = "이전 페이지")
            }

            Button(
                onClick = {
                    coroutineScope.launch {
                        if(pagerState.currentPage >= MAX_COUNT) return@launch
                        pagerState.animateScrollToPage(pagerState.currentPage + 1)
                    }

                }
            ) {
                Text(text = "다음 페이지")
            }
        }

        HorizontalPager( // 가로로 스크롤 가능한 pager
            count = MAX_COUNT, // 페이지 수
            state = pagerState // PagerState
        ) { page ->
            // 페이지 content
            CardView(text = "Card $page")
        }

        HorizontalPagerIndicator( // pager indicator
            pagerState = pagerState,
            modifier = Modifier
                .align(Alignment.CenterHorizontally)
                .padding(16.dp),
        )
    }
}

📌 Pager + Tab

@OptIn(ExperimentalPagerApi::class)
@Composable
fun MyTabPagerView(){
    val tabPagerState = rememberPagerState()
    val coroutineScope = rememberCoroutineScope()

    val tabs = MyTab.values().toList()
    val pages = mutableListOf<@Composable ()->Unit>(
        { CardView(text = MyTab.HOME.title) },
        { CardView(text = MyTab.PROFILE.title) },
        { CardView(text = MyTab.LIST.title) },
        { CardView(text = MyTab.SETTING.title) },
    )

    Column() {
        TabRow(
            // Our selected tab is our current page
            selectedTabIndex = tabPagerState.currentPage,
            // Override the indicator, using the provided pagerTabIndicatorOffset modifier
            indicator = { tabPositions ->
                TabRowDefaults.Indicator(
                    Modifier.pagerTabIndicatorOffset(tabPagerState, tabPositions)
                )
            }
        ) {
            // Add tabs for all of our pages
            tabs.forEachIndexed { index, tabItem ->
                Tab(
                    text = { Text(tabItem.title) },
                    selected = tabPagerState.currentPage == index,
                    onClick = {
                              coroutineScope.launch {
                                  tabPagerState.animateScrollToPage(index)
                              }
                    },
                )
            }
        }

        // Display 10 items
        HorizontalPager(
            count = tabs.size,
            state = tabPagerState
        ) { page ->
            pages[page]()
        }
    }
}

Pager 의 page 마다 각각 다른 composable 을 호출할 수 있는 방법에 대해서 생각해봤습니다.
제가 생각해낸 방법은 @Composable ()-> Unit 자료형을 갖는 list 를 만들어서 컴포저블 함수를 넣어두고, 사용하는 것 입니다.

이렇게 사용하는 것이 맞는지는 모르겠지만, 일단 잘 동작합니다.

예제이기 때문에 4개의 페이지 모두 CardView 로 text 값만 다르게 줬지만, 이를 응용하면 page 마다 각각 다른 composable 함수를 호출 할 수 있을 것 같습니다.

📌 CardView

@Composable
fun CardView(text: String){
    Card(
        modifier = Modifier.padding(50.dp),
        backgroundColor = Color.Yellow,
        elevation = 10.dp
    ) {
        Text(
            text = text,
            fontSize = 20.sp,
            fontWeight = FontWeight.Bold,
            textAlign = TextAlign.Center,
            modifier = Modifier.padding(100.dp)
        )
    }
}
profile
매일 조금씩이라도 성장하자
post-custom-banner

0개의 댓글