Reputation: 1005
Box(
modifier = Modifier.size(100.dp),
contentAlignment = Alignment.Center
) {
val pagerState = rememberPagerState()
val items = listOf("A", "B", "C")
androidx.compose.foundation.pager.HorizontalPager(
state = pagerState,
pageCount = items.size,
modifier = Modifier,
verticalAlignment = Alignment.CenterVertically
) { page ->
Text(
text = items[page],
modifier = Modifier
)
}
}
In the above code, the pager stops scrolling after reaching the last item. However, I want the pager to continue scrolling endlessly after reaching the last item.
Upvotes: 7
Views: 4421
Reputation: 2808
One small addition to this topic. I noticed that whenever the pageCount
changes, the rememberPagerState
will not be updated. In this case using the HorizontalPager position with % items.size
breaks the calculation and leads to wrong results. Here is a sample that does not have this problem:
@Composable
fun InfiniteHorizontalPager(
pageCount: Int,
modifier: Modifier = Modifier,
initialPage: Int = 0,
content: @Composable PagerScope.(page: Int) -> Unit,
) {
val max = Short.MAX_VALUE.toInt()
val half = max / 2
val pagerPositionIndex = initialPage + half - half % pageCount
val pagerState = rememberPagerState(pageCount = { max }, initialPage = pagerPositionIndex)
LaunchedEffect(pagerPositionIndex, pageCount) {
pagerState.scrollToPage(pagerPositionIndex)
}
HorizontalPager(
state = pagerState,
userScrollEnabled = pageCount > 1,
modifier = modifier,
) { index ->
val page = index % pageCount
this.content(page)
}
}
Upvotes: 2
Reputation: 67248
You can create it by setting pageCount to Int.MAX_VALUE and getting modulus of current page to get index for your list of items.
@Preview
@Composable
private fun Test() {
val pageCount = Int.MAX_VALUE
val items = listOf("A", "B", "C")
val pagerState = rememberPagerState(
initialPage = pageCount / 2
)
HorizontalPager(
modifier = Modifier.fillMaxWidth(),
pageCount = pageCount,
state = pagerState
) {
Text(text = items[it % 3])
}
}
As of Compose version 1.6.0 Int.MAX_VALUE(2147483647)
causes pager to have ANR, to prevent this add a big number but smaller than 2147483647 that user won't bother to scroll that far.
@Preview
@Composable
private fun InfinitePagerSample() {
Column(
modifier = Modifier
.fillMaxSize()
.padding(16.dp)
.border(2.dp, Color.Red)
) {
val items = remember {
listOf("A", "B", "C")
}
val pageCount = items.size * 400
val pagerState = rememberPagerState(
initialPage = pageCount / 2,
pageCount = {
pageCount
}
)
HorizontalPager(
modifier = Modifier.fillMaxWidth(),
state = pagerState,
beyondBoundsPageCount = 1
) {
val color = if (it % items.size == 0) {
Color.Red
} else if (it % items.size != 1) {
Color.Yellow
} else Color.Green
Column(modifier = Modifier.fillMaxSize().background(color)) {
SideEffect {
println("Page $it, composing...")
}
Text(text = items[it % 3], modifier = Modifier.fillMaxSize(), fontSize = 70.sp)
}
}
}
}
Upvotes: 13