How to keep same slide state in Nested LazyColumn?

Issue

enter image description here

A LazyColumn includes another LazyColumn, and the second LazyColumn includes a HorizontalPager. Each pager include a list.

How to solve this issue, or does anyone have another idea better to implement the function? I provided a gif about the sample.

Problem: I would like to make the entire layout slide together by sliding the LazyColumn below. However, in my implementation, only the LazyColumn below slides and cannot make the entire page slide upwards as it slides

@Composable
fun RadioStationPage(viewModel: RadioStationViewModel = hiltViewModel()){
   ...
        LazyColumn(
            state = listState,
            modifier = Modifier.fillMaxSize()
        ){
        ...
                  item { ProgramRankPager( ... )}
    }
}
@Composable
private fun ProgramRankPager(
   ...
){
    Column(
        modifier = Modifier .fillMaxWidth()
.heightIn(max = LocalConfiguration.current.screenHeightDp.dp)
    ) {
        TabRow(
           ...
        ) {
             tabs.forEachIndexed { index, rankTab ->
               ...
            }
        }
        HorizontalPager(
            count = pagers.size,
            state = pageState,
            modifier = Modifier.weight(1f)

        ) {
            //include three page,Simplified into one
            ProgramRankList(...)
            SecondPage()
            ThirdPage()
        }
    }
}

@Composable
private fun ProgramRankList(...){
    LazyColumn(
        modifier = Modifier.fillMaxSize()//...
    ){
        ...
        items(items = programStatus){ item->
            item?.let { bean->
                ProgramRankListItem(
                   ...
                )
            }
        }

    }
}

Solution

As no one has answered yet, I’ll give it a shot.

I think there is a conceptual design flaw in what you are trying to achieve. Let me point out some things that I consider to be difficult:

  • You have two scrollable LazyColumns where one is a child of the other. In Jetpack Compose, this only is possible if the nested LazyColumn has a fixed height. In your case, this seems to be okay as you set a height to the parent of the nested LazyColumn by setting Modifier.weight(1f) to the HorizontalPager, and then just fill that height in your nested LazyColumn.

  • However, using this Modifier.weight(1f) does not really make sense on a child of another LazyColumn. It will probably do nothing, or it will push all other content off screen, or it may lead to unpredictable behavior.

  • If you combine two LazyColumns and have the inner one with fixed size, you can only scroll the inner one by scrolling with your finger exactly on top of it. If you want to scroll the outer LazyColumn, you have to scroll in an area outside of the inner LazyColumn.

To sum this up, if you want to make the outer LazyColumn scroll by swiping on the inner LazyColumn, then you have to make the inner LazyColumn non-scrollable. You can disable scrolling on the nested LazyColumn with the following code:

@Composable
fun ProgramRankList(...){
    LazyColumn(
        modifier = Modifier.fillMaxSize(),
        userScrollEnabled = false,  // disable scrolling
        //...
    ){
        //...
    }
}

Then, only the outer LazyColumn will consume the scroll event, and will make the whole page scroll.

However, I feel like you should rethink your UI design or explain more clearly what exact scrolling behavior you want to achieve, in case I did not understand properly.

Answered By – BenjyTec

Answer Checked By – Cary Denson (FlutterFixes Admin)

Leave a Reply

Your email address will not be published. Required fields are marked *