🐻❄️
[Jetpack Compose]無限ループするViewPagerを作成する
実装方法
ViewPager
のページ数をInt最大値に設定して、0〜Int最大値の範囲に特定のデータを繰り返し表示して、無限ループするViewPager
を作成する。
@OptIn(ExperimentalFoundationApi::class)
@Composable
fun LoopViewPager() {
// 表示する3つのテキストデータ
val texts = listOf("ONE", "TWO", "THREE")
val textCount = texts.count()
// ページカウントをInt最大値にして、実質無限回スワイプできるようにする
val dummyPageCount = Int.MAX_VALUE
// 左右にスワイプしてすぐに先頭・最後尾に到達しないように初期ページ位置を全てのページの真ん中の位置に設定する
val pagerState = rememberPagerState(
initialPage = (dummyPageCount / textCount / 2) * textCount
)
Column(
verticalArrangement = Arrangement.spacedBy(16.dp)
) {
// Int最大値の要素を表示するViewPager
HorizontalPager(pageCount = dummyPageCount, state = pagerState) { dummyIndex ->
// 実際に表示するテキストデータは3つなので、それぞれの場所に繰り返し3つのテキストデータが表示されるようにする
val text = texts[dummyIndex % textCount]
Card(modifier = Modifier.size(256.dp)) {
Box(modifier = Modifier.fillMaxSize()) {
Text(
text = text,
fontSize = 32.sp,
modifier = Modifier.align(Alignment.Center)
)
}
}
}
// ViewPagerで表示されているテキストデータの位置を表すインジケータ
Row(
horizontalArrangement = Arrangement.spacedBy(16.dp),
modifier = Modifier.align(Alignment.CenterHorizontally)
) {
repeat(textCount) { index ->
// PagerStateには0〜Int最大値の値が入ってくる
val currentDummyIndex = pagerState.currentPage
// 0〜Int最大値の範囲で3つのデータが繰り返し表示されている。
// 繰り返し表示されている3つのデータのうちどれが表示されているか算出する
val currentIndex = currentDummyIndex % textCount
// データの表示状況に応じて、インジケータの色を変更する
val color = if (currentIndex == index) Color.Red else Color.LightGray
Box(
modifier = Modifier
.background(shape = CircleShape, color = color)
.size(16.dp)
)
}
}
}
}
Discussion