Tving 앱 클론 코딩 중 "홈 화면 구현"이라는 과제를 받았습니다.
실제 티빙을 참고해보면 배너가 아래의 조건을 만족하고 있습니다.
- 슬라이딩을 통해 다음 포스터로 넘어갈 수 있어야 한다.
- 포스터 하나가 화면을 꽉 채우지 않고, 이전/이후 포스터가 가장자리에 조금 표시되어야 한다.
뭐.. 이외에도 티빙에서는 시간이 지나면 포스터를 자동으로 넘겨주기도 하는데, 저는 약식으로 위의 두 조건에 대해서만 고려해보려 했습니다.
아무튼 위의 기능 구현을 위해서 캐러셀이라는 키워드로 자료를 찾아 구현해보았습니다.
그래서 이번 포스트로는 배너 캐러셀 구현 방법에 대해 다뤄보겠습니다.
@Composable
fun BannerCarousel(
bannerImageList: ImmutableList<Int>,
modifier: Modifier = Modifier
) {
val pagerState = rememberPagerState(
initialPage = 0,
pageCount = { bannerImageList.size }
)
Column(
modifier = modifier.fillMaxSize()
) {
HorizontalPager(
state = pagerState,
contentPadding = PaddingValues(horizontal = dimensionResource(R.dimen.screen_padding_horizontal)),
pageSpacing = dimensionResource(R.dimen.content_default_spacing),
modifier = Modifier
) { pageIndex ->
Image(
painter = painterResource(bannerImageList[pageIndex]),
contentDescription = "banner",
contentScale = ContentScale.FillWidth,
modifier = Modifier
.fillMaxWidth()
.height(450.dp)
.clip(RoundedCornerShape(12.dp)),
)
}
}
}
다른 라이버러리 일절 없이 코드로 간단하게 구현할 수 있었어요.
pageState에 initialPage와 pageCount를 설정해 줍니다.
HorizontalPager에 state를 넘겨주고, contentPading과 pageSpacing을 설정해줍니다.
contentPadding은 가장 첫번쨰와 마지막 아이템을 화면에서 얼마나 띄워줄지의 간격이고, pageSpacing은 아이템 간의 간격입니다.
contentScale은 ContentScale.FillWidth로 설정해 아이템이 화면을 꽉 채울 수 있게끔 해주었습니다.
컴포넌트로 만든 BannerCarousel을 사용처에서 불러오면 작업은 끝납니다!
val bannerImageList = listOf<Int>(
R.drawable.img_poster_ex1,
R.drawable.img_poster_ex2,
R.drawable.img_poster_ex3,
R.drawable.img_poster_ex4,
)
LazyColumn(
modifier = Modifier.fillMaxSize()
) {
// TopBar, TabLayout 등 위치
item {
BannerCarousel(
bannerImageList = bannerImageList
)
}
}
티빙의 홈 화면은 복잡하게 구성되어 있었기에 저는 LazyColumn의 item으로 BanerCarousel을 넣어줬어요.
약식으로 포스터만 넣고, 직접 슬라이드로 넘길 수 있게 구현했습니다!
추가 기능으로는 앞서 잠깐 언급했듯이 시간이 지나면 페이지를 자동으로 넘기거나, 아니면 실제 티빙처럼 포스트 이미지 말고도 콘텐츠 설명을 포스터 위로 표시해준다던가, 할 수도 있을 거 같아요.
모쪼록 제가 작성한 포스터가 누군가에게는 도움이 되기를 바라봅니다.