LazyColumn inside HorizontalPager becomes scrollable with a delay after page changed

172 Views Asked by At

I am working on a an android jetpack compose screen. Simply, the page has a TabRow with 3 tabs. Every tab has LazyColumn which shows some ui components in a scrollable manner. Also, there is one HorizontalPager, which contains these LazyColumns, for the user to swipe between tabs nicely.

Here is the code;

@Composable
fun StatsContent(viewModel: StatsViewModel) {
    val state = viewModel.soloGameStatsState.collectAsStateWithLifecycle()
    LaunchedEffect(LocalContext.current) {
        viewModel.getSoloStats()
    }

    val titles = listOf("Tab 1", "Tab 2", "Tab 3")
    val pagerState = rememberPagerState { titles.size }
    var tabIndex = pagerState.currentPage
    val coroutineScope = rememberCoroutineScope()

    Scaffold(
        topBar = {
            TabRow(selectedTabIndex = tabIndex) {
                titles.forEachIndexed { index, title ->
                    Tab(
                        text = { Text(title) },
                        selected = tabIndex == index,
                        onClick = { tabIndex = index
                            coroutineScope.launch {
                                pagerState.animateScrollToPage(index)
                            }
                        }
                    )
                }
            }
        },
        content = { paddingValues ->
                HorizontalPager(
                    state = pagerState,
                    pageSpacing = 16.dp
                ) {
                    Column(
                        modifier = Modifier
                            .padding(paddingValues)
                            .fillMaxSize(),
                        verticalArrangement = Arrangement.Center,
                        horizontalAlignment = Alignment.CenterHorizontally
                    ) {
                        if (tabIndex == 1 || tabIndex == 0) {
                            RenderStatsOne(state.value)
                        } else if (tabIndex == 2) {
                            RenderStatsTwo(stats = state.value)
                        }
                    }
                }

        }
    )
}
@Composable
fun RenderStatsOne(stats: Stats?) {
    if (stats != null) {
        LazyColumn(
            modifier = Modifier
                .fillMaxSize()
                .paint(
                    painterResource(id = R.drawable.bg_results),
                    contentScale = ContentScale.Crop
                )
        ) {
            item { ...

@Composable
fun RenderStatsTwo(stats: Stats?) {
    if (stats != null) {
        LazyColumn(
            modifier = Modifier
                .fillMaxSize()
                .paint(
                    painterResource(id = R.drawable.bg_results),
                    contentScale = ContentScale.Crop
                )
        ) {
            item { ...

Here is the issue; Once a page change occurred, it does not matter user triggered it with a tab click or did left-right swipe on the pager, the LazyColumn inside the new visible page is becomes scrollable with a significant delay. Therefore, when I change the page and then quickly try to swipe up and down, the HorizontalPager gets this gesture and a page change is performed.

I see that pagerState has a field called isScrollInProgress. This becomes true as the scroll started. LazyColumn gets focus and becomes scrollable, only when this field becomes false. Unfortunately, this becomes false with a significant delay after the page change is completed.

I am looking for a solution which will make the LazyColumn scrollable as soon as the the new page content it fullu visible.

Any help? Thanks a lot in advance.

0

There are 0 best solutions below