Ora

How to make a Column scrollable in Compose?

Published in Jetpack Compose UI 5 mins read

To make a Column scrollable in Jetpack Compose, you apply the Modifier.verticalScroll() modifier, typically combined with a rememberScrollState() to manage and observe its scroll position.

How to Make a Column Scrollable in Compose?

Making a Column scrollable in Jetpack Compose is straightforward and primarily involves applying a specific modifier. This enables content that exceeds the screen's vertical boundaries to be viewed by user interaction, effectively extending the visible content area and allowing access to all elements, even those initially off-screen.

Using Modifier.verticalScroll()

The Modifier.verticalScroll() is the key to adding vertical scrolling capabilities to a composable. When applied to a Column, it allows the content within that Column to be scrolled up and down.

Syntax:

Column(
    modifier = Modifier
        .verticalScroll(rememberScrollState())
        // Other modifiers like fillMaxSize(), padding(), etc.
) {
    // Your content goes here
}

Understanding the Core Components

Two main components work together to create a scrollable Column:

  1. Modifier.verticalScroll(scrollState): This is the actual modifier that enables scrolling. It requires a ScrollState object to manage its internal state.
  2. rememberScrollState(): This function creates and remembers a ScrollState instance across recompositions. The ScrollState holds information about the current scroll position and provides methods to control scrolling programmatically.

The Role of ScrollState

The ScrollState object is crucial because it:

  • Manages Scroll Position: Keeps track of how far the content has been scrolled.
  • Enables Programmatic Scrolling: Allows you to scroll to a specific position using methods like scrollBy() or scrollTo().
  • Observes Scroll Position: You can observe changes to the scroll position for UI updates or logic.

Practical Example: A Basic Scrollable Column

Here's a simple example demonstrating how to make a Column scrollable. This setup allows you to display a long list of items, such as a sequence of "Features," where you can scroll to view items beyond the initial screen boundary.

import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp

@Composable
fun ScrollableColumnExample() {
    // 1. Create and remember a ScrollState
    val scrollState = rememberScrollState()

    Surface(
        modifier = Modifier.fillMaxSize(),
        color = MaterialTheme.colorScheme.background
    ) {
        // 2. Apply Modifier.verticalScroll to the Column
        Column(
            modifier = Modifier
                .fillMaxSize()
                .verticalScroll(scrollState) // This makes the column scrollable
                .padding(16.dp)
        ) {
            // Content that will exceed the screen height
            repeat(50) { index ->
                Text(
                    text = "Feature number ${index + 1}",
                    modifier = Modifier
                        .fillMaxWidth()
                        .padding(vertical = 8.dp)
                        .background(if (index % 2 == 0) Color.LightGray else Color.Transparent)
                )
            }
        }
    }
}

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

In this example, the Column contains 50 Text composables. Since most screens cannot display 50 items simultaneously, applying .verticalScroll(scrollState) makes the column scrollable, giving you access to all "Feature number" items (like 11, 12, 13, and 40 from an expanded list) by simply scrolling.

Customizing Scroll Behavior

The Modifier.verticalScroll() modifier offers additional parameters for customization:

  • enabled: A boolean (default true) to enable or disable scrolling.
  • flingBehavior: Defines how the scroll behaves when the user "flings" the content (i.e., scrolls rapidly and releases). You can create custom fling behaviors for unique scrolling effects.
  • reverseScrolling: A boolean (default false) that, when set to true, reverses the direction of scrolling. Scrolling down will move content up, and scrolling up will move content down.

Column with verticalScroll vs. LazyColumn

While Modifier.verticalScroll() makes a Column scrollable, it's essential to understand its limitations compared to LazyColumn for performance.

Feature Column with Modifier.verticalScroll LazyColumn
Performance Renders all items at once, regardless of visibility. Can be inefficient for very long lists. Renders only visible items (and a small buffer). Highly efficient for large datasets.
Composition Scope All child composables are composed and laid out. Composes items on demand as they scroll into view.
Use Case When you have a small to moderate number of items that fit within a few screen heights.
When you need to apply complex layout modifiers to the entire column, such as different paddings or backgrounds that affect the whole container rather than individual items.
When you have a large or infinite number of items.
When you need to optimize performance and memory usage for lists.
API Uses Column composable with a Modifier. Provides its own LazyColumn composable.

Recommendation: For long lists (e.g., more than ~10-20 items that may exceed screen height), always prefer LazyColumn for optimal performance. Use Column with Modifier.verticalScroll() for scenarios where the content is not excessively long, or when you need the entire content to be present in the composition tree for specific reasons.

Accessibility Considerations

When creating scrollable content, ensure that the scroll indicators are visible and that the content is structured logically. Users with accessibility needs should be able to navigate and understand the content, regardless of their preferred input method.

By following these steps, you can effectively make any Column in your Jetpack Compose application scrollable, providing a seamless user experience for content that extends beyond the initial display area.