Android - How to listen to scroll in a Column modifier.verticalScroll

143 Views Asked by At

In Compose I am finding no way to listen to a list when it scrolls and react accordingly.

The main goal is to change a TopAppBar elevation according to how much the bottom list scrolls up or down; the bar elevation increases to 3 and decreases to 0 respectively, but so far I haven't even been able to listen to something as simple as the scroll of the content list below it.

This is how I have the content below the scaffold that contains the top bar:

// this is inside a composable
    val scrollState = rememberScrollState()

    Column(
        modifier = Modifier
            .fillMaxWidth()
            .wrapContentHeight()
            .padding(paddingValues)
            .verticalScroll(
                state = scrollState,
                enabled = true,
            )
    ) {

        // multiple list items here

    }

I cannot find any way to either listen to when scrollState changes, or when the Column scroll changes.

Available documentation shows nothing for this as far as I could find, nor could I find anything in SO either.

The only closest thing I found so far is strictly when using LazyColumn which I am not.

I could do this incredibly easily with kotlin + xml layouts, but when it comes to compose something that should be very simple like this feels impossible, how can this be done?

1

There are 1 best solutions below

0
On BEST ANSWER

You can do it with NestedScrollConnection. You need to constrain bottom value to 0 and max value to maximum allowed by scrollState.

@Preview
@Composable
fun NestedScrollSample() {

    var offset by remember {
        mutableStateOf(0f)
    }

    val scrollState = rememberScrollState()
    val nestedScrollConnection = remember {
        object : NestedScrollConnection {
            override fun onPreScroll(available: Offset, source: NestedScrollSource): Offset {
                offset = (offset - available.y).coerceIn(0f, scrollState.maxValue.toFloat())
                return Offset.Zero
            }
        }
    }

    Column {
        Text(text = "Offset: $offset")

        Column(
            modifier = Modifier
                .nestedScroll(nestedScrollConnection)
                .fillMaxSize()
                .verticalScroll(state = scrollState)
        ) {
            repeat(100) {
                Text(
                    modifier = Modifier
                        .fillMaxWidth()
                        .background(Color.Green)
                        .padding(8.dp),
                    text = "Row $it",
                    color = Color.Red,
                    fontSize = 20.sp
                )
            }
        }
    }
}