kotlinhorizontal-scrollingandroid-jetpack-compose

Is there a way to make two way HorizontalPager with auto scroll?


The HorizontalPager from accompanist library does a job of creating a simple ViewPager; is there a way to swipe infinitely in both ends?

@ExperimentalPagerApi
@Composable
fun AutoScrollPagerHorizontal(d: List<Stem>?) {
    var data: MutableList<Stem> = d?.toMutableList() ?: mutableListOf()

    if (data.isNullOrEmpty()) return
    val pageState = rememberPagerState(pageCount = data.size)
    HorizontalPager(
        state = pageState
    ) {
        Card(
            Modifier
                .height(240.dp)
                .padding(start = 16.dp, end = 16.dp, top = 8.dp, bottom = 8.dp)
        ) {
            Image(
                painter = rememberGlidePainter(
                    request = data[it].icon,
                ),
                contentDescription = data[it].title,
                contentScale = ContentScale.FillBounds
            )
        }
    }
}

This code generates the viewpager correctly, but does not scroll to 0th index after reaching the last index of data.


Solution

  • PointerInput helped in building the bi-directional Pager; below is the snippet that worked for me.

    Modifier.pointerInput(Unit) {
                        detectHorizontalDragGestures { change, dragAmount ->
                            change.consumeAllChanges()
                            when {
                                dragAmount < 0 -> {
                                    coroutineScope.launch { /* right */
                                        if (pageState.currentPage == data.lastIndex) {
                                            pageState.animateScrollToPage(0)
                                        } else {
                                            pageState.animateScrollToPage(pageState.currentPage + 1)
                                        }
                                    }
                                }
                                dragAmount > 0 -> { /* left */
                                    coroutineScope.launch {
                                        if (pageState.currentPage == 0) {
                                            pageState.animateScrollToPage(data.lastIndex)
                                        } else {
                                            pageState.animateScrollToPage(pageState.currentPage - 1)
                                        }
                                    }
                                }
                            }
                        }
                    }