오늘은 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
@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),
)
}
}
@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 함수를 호출 할 수 있을 것 같습니다.
@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)
)
}
}