|

How to Add Scroll to Top Button with LazyColumn in Android Jetpack Compose

When building large lists in Android, Jetpack Compose’s LazyColumn is a fantastic tool in your arsenal. But what happens when your users have scrolled way down in the list and want a quick way to get back to the top? Enter the Scroll to Top button.

In this blog post, I’ll demonstrate adding a Scroll to the Top button in a LazyColumn using Jetpack Compose. We’ll use the following example:

@Composable
fun ScrollableColumnExample() {
    val coroutineScope = rememberCoroutineScope()
    val listState = rememberLazyListState()

    Box(modifier = Modifier.fillMaxSize()) {
        LazyColumn(state = listState) {
            items(100) { item ->
                Text(text = "Item $item", modifier = Modifier.fillMaxWidth())
            }
        }

        Button(onClick = {
            coroutineScope.launch {
                listState.animateScrollToItem(index = 0)
            }
        },
            modifier = Modifier
                .align(Alignment.BottomCenter)
                .padding(16.dp)) { // Add some padding at the bottom
            Text("Scroll to top")
        }
    }
}

Here’s a breakdown of how this works:

We start by creating a LazyColumn inside a Box that fills the maximum size of its parent. The Box allows us to layer multiple elements (in our case, the LazyColumn and Button).

We use rememberCoroutineScope() to get a CoroutineScope which is tied to the lifecycle of the composable where it’s called. This scope is used to launch coroutines that can manage long-running tasks such as scrolling the list.

We use rememberLazyListState() to remember the state of our LazyColumn. This state object allows us to control the scroll position.

Inside the Box, we first have our LazyColumn which generates 100 text items.

Following the LazyColumn, we have a Button composable which is aligned to the bottom center of the Box and includes some padding at the bottom. The text inside the button says “Scroll to top”.

When the button is clicked, we launch a coroutine within the earlier remembered coroutine scope. Inside this coroutine, we call listState.animateScrollToItem(index = 0). This animates the scroll position of the LazyColumn back to the top.

jetpack compose lazycolumn scroll to top

Following is the complete code for reference.

package com.example.example

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.material3.Button
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.example.example.ui.theme.ExampleTheme
import kotlinx.coroutines.launch

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            ExampleTheme {
                // A surface container using the 'background' color from the theme
                Surface(
                    modifier = Modifier.fillMaxSize(),
                    color = MaterialTheme.colorScheme.background
                ) {
                    ScrollableColumnExample()
                }
            }
        }
    }
}

@Composable
fun ScrollableColumnExample() {
    val coroutineScope = rememberCoroutineScope()
    val listState = rememberLazyListState()

    Box(modifier = Modifier.fillMaxSize()) {
        LazyColumn(state = listState) {
            items(100) { item ->
                Text(text = "Item $item", modifier = Modifier.fillMaxWidth())
            }
        }

        Button(onClick = {
            coroutineScope.launch {
                listState.animateScrollToItem(index = 0)
            }
        },
            modifier = Modifier
                .align(Alignment.BottomCenter)
                .padding(16.dp)) { // Add some padding at the bottom
            Text("Scroll to top")
        }
    }
}

@Preview(showBackground = true)
@Composable
fun ExamplePreview() {
    ExampleTheme {
        ScrollableColumnExample()
    }
}

And that’s it! With this setup, no matter how far down your users have scrolled in the list, they can return to the top with just a click. This addition significantly enhances user experience, especially when dealing with long lists.

Similar Posts

Leave a Reply