- (擬似的に)無限ループしたい
- タップされているときは自動送りしない
- private const val PAGE_COUNT = 10_000
- private const val INITIAL_PAGE = PAGE_COUNT / 2
-
- private fun Int.floorMod(other: Int): Int = when (other) {
- 0 -> this
- else -> this - this.floorDiv(other) * other
- }
-
- @Composable
- fun AutoScrollHorizontalPager(
- itemSize: Int,
- modifier: Modifier = Modifier,
- autoScrollDuration: Long = 2_000L,
- onPageChanged: ((page: Int) -> Unit)? = null,
- pageContent: @Composable PagerScope.(page: Int) -> Unit,
- ) {
- val pagerState = rememberPagerState(INITIAL_PAGE) { PAGE_COUNT }
-
- fun Int.toIndex(): Int = (this - INITIAL_PAGE).floorMod(itemSize)
-
- if (onPageChanged != null) {
- LaunchedEffect(onPageChanged) {
- snapshotFlow { pagerState.currentPage }
- .collect { page -> onPageChanged(page.toIndex()) }
- }
- }
-
- val dragged by pagerState.interactionSource.collectIsDraggedAsState()
- if (!dragged) {
- LaunchedEffect(Unit) {
- while (true) {
- delay(autoScrollDuration)
-
- val nextPage = pagerState.currentPage + 1
- if (nextPage < PAGE_COUNT) {
- pagerState.animateScrollToPage(nextPage)
- } else {
- pagerState.scrollToPage(0)
- }
- }
- }
- }
-
- HorizontalPager(
- state = pagerState,
- modifier = modifier,
- ) { page ->
- pageContent(page.toIndex())
- }
- }
private const val PAGE_COUNT = 10_000
private const val INITIAL_PAGE = PAGE_COUNT / 2
private fun Int.floorMod(other: Int): Int = when (other) {
0 -> this
else -> this - this.floorDiv(other) * other
}
@Composable
fun AutoScrollHorizontalPager(
itemSize: Int,
modifier: Modifier = Modifier,
autoScrollDuration: Long = 2_000L,
onPageChanged: ((page: Int) -> Unit)? = null,
pageContent: @Composable PagerScope.(page: Int) -> Unit,
) {
val pagerState = rememberPagerState(INITIAL_PAGE) { PAGE_COUNT }
fun Int.toIndex(): Int = (this - INITIAL_PAGE).floorMod(itemSize)
if (onPageChanged != null) {
LaunchedEffect(onPageChanged) {
snapshotFlow { pagerState.currentPage }
.collect { page -> onPageChanged(page.toIndex()) }
}
}
val dragged by pagerState.interactionSource.collectIsDraggedAsState()
if (!dragged) {
LaunchedEffect(Unit) {
while (true) {
delay(autoScrollDuration)
val nextPage = pagerState.currentPage + 1
if (nextPage < PAGE_COUNT) {
pagerState.animateScrollToPage(nextPage)
} else {
pagerState.scrollToPage(0)
}
}
}
}
HorizontalPager(
state = pagerState,
modifier = modifier,
) { page ->
pageContent(page.toIndex())
}
}