1

I have a 3 Column. In 1st Column of components are 2nd and 3rd Column. In 2nd Column there are so many components inside that. In last 3rd Column I have a few items and I am sticking at the bottom of screen. I have done with the help of this answer. In smaller screen item is going behind, so my supervisor mention that all item will automatically scroll of 2nd Column which is clearly above of 3rd Column.

@Composable
fun Xyz(){
    Theme {
        Column(
            modifier = Modifier
                .padding(dimensionResource(R.dimen.margin_screen_edge_sides))
                .fillMaxSize()
                .verticalScroll(rememberScrollState()),
//            verticalArrangement = Arrangement.Top
            or
//                verticalArrangement = Arrangement.Arrangement.SpaceBetween
        ) {
            Column(
                modifier = Modifier
                    .verticalScroll(rememberScrollState())
                    .weight(1f),
                horizontalAlignment = Alignment.CenterHorizontally,
            ) {
                // so many item in here.
               //  If here items is behind of 3rd column then automatically scroll the item when user land of this this screen
            }
            Column {
                Button()
                // may be more item in here
            }
        }
    }
}

Actual Output

enter image description here

Expected Output

Scenario 1

enter image description here

Note:- Item will be increase in 2nd Column i.e. I added logic in AnimatedVisibility so when recompose it will added the item.

Scenario 2

When no item is going behind the 3rd Column then my screen will not scroll anything

enter image description here

if you have question please ask me. Many Thanks

UPDATE

@Composable
fun Xyz(){
    Theme {
        val scrollState = rememberScrollState()

        LaunchedEffect(
            keyOneIsTrue,
            keyTwoIsTrue
        ) {
            val newValue = scrollState.maxValue
            scrollState.animateScrollTo(newValue)
        }
        Column(
            modifier = Modifier
                .padding(dimensionResource(R.dimen.margin_screen_edge_sides))
                .fillMaxSize()
                .verticalScroll(rememberScrollState()),
//            verticalArrangement = Arrangement.Top
            or
//                verticalArrangement = Arrangement.Arrangement.SpaceBetween
        ) {
            Column(
                modifier = Modifier
                    .verticalScroll(scrollState)
                    .weight(1f),
                horizontalAlignment = Alignment.CenterHorizontally,
            ) {
                // so many item in here.
                //  If here items is behind of 3rd column then automatically scroll the item when user land of this this screen
            }
            Column {
                Button()
                // may be more item in here
            }
        }
    }
}

I have so many keys but I am giving you few example in my LaunchedEffect. When keyOneIsTrue it goes inside the LaunchedEffect and then newValue always return 0 value. This is same happening in keyTwoIsTrue and nothing will scroll :(

Note when any key change it means I am changing visibility of items in 2nd Column by the help of AnimatedVisibility

UPDATE 2

I am adding real time example which is auto scrolling are not working when item is added in the list.

@Preview(showBackground = true, widthDp = 250, heightDp = 320)
@Composable
fun Xyz() {
    Theme {
        var itemClicked by remember { mutableStateOf(0) }
        val favourites = remember { mutableStateListOf<String>() }
        val scrollState = rememberScrollState()
        LaunchedEffect(favourites.size > 0) {
            scrollState.animateScrollTo(scrollState.maxValue)
        }
        Column(
            modifier = Modifier
                .padding(dimensionResource(R.dimen.margin_screen_edge_sides))
                .fillMaxSize()
                .verticalScroll(rememberScrollState()),
        ) {
            Column(
                modifier = Modifier
                    .verticalScroll(scrollState)
                    .weight(1f),
                horizontalAlignment = Alignment.CenterHorizontally,
            ) {
                favourites.forEach { text ->
                    Text(
                        text = text,
                        fontSize = 30.sp,
                        color = Red
                    )
                }
            }
            Column {
                Button(onClick = {
                    itemClicked++
                    favourites.add("item clicked $itemClicked")
                }) {
                    Text(text = "Add me")
                }
            }
        }
    }
}

You can clearly see in video when item add in the list the auto scroll is not working. It only scrolling when user do manually.

Kotlin Learner
  • 3,995
  • 6
  • 47
  • 127
  • block inside `LaunchedEffect(favourites.size > 0)` gets invoked on composition then when size is greater than 0. It doesn't matter what current size is as LaunchedEffect is concerned. You need to use favorites.size as key. Or call scroll when you add items. In this messaging sample i scroll to last message when new message is added. https://github.com/SmartToolFactory/Flexible-Chat-Box/blob/master/app/src/main/java/com/smarttoolfactory/dynamicmessagebox/DemoFullChat.kt – Thracian Dec 07 '22 at 12:18

1 Answers1

3

You can use the ScrollState to scroll the content of the Column.

val scrollState = rememberScrollState()

Column(
   //...
){
    Column(
        Modifier
            .verticalScroll(scrollState)
    //....
}

Then you can use your favorite logic to scroll the content. For example when the screen is loaded:

LaunchedEffect(Unit){
    scrollstate.animateScrollTo(scrollstate.maxValue)
}

If you have a list and you want to scroll when a new item is loaded inside the scrollable Column:

val favourites = remember { mutableStateListOf<String>() }
val scrollState = rememberScrollState()

LaunchedEffect(favourites.size) {
    scrollState.animateScrollTo(scrollState.maxValue)
}

enter image description here

Gabriele Mariotti
  • 320,139
  • 94
  • 887
  • 841