You can apply scrollbars to scrollable components. The scrollbar and scrollable components share a common state to synchronize with each other.
The verticalScroll
and horizontalScroll
modifiers provide the simplest way to allow the user to scroll an element when the bounds of its contents are larger than its maximum size constraints. You can attach the VerticalScrollbar
composable to a scrollable component with the verticalScroll
modifier and the HorizontalScrollbar
composable to a scrollable component with the horizontalScroll
modifier:
import androidx.compose.foundation.HorizontalScrollbar
import androidx.compose.foundation.VerticalScrollbar
import androidx.compose.foundation.background
import androidx.compose.foundation.horizontalScroll
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.rememberScrollbarAdapter
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.WindowState
import androidx.compose.ui.window.singleWindowApplication
fun main() = singleWindowApplication(
title = "Scrollbars",
state = WindowState(width = 300.dp, height = 310.dp)
) {
Box(
modifier = Modifier.fillMaxSize()
.background(color = Color(180, 180, 180))
.padding(10.dp)
) {
val stateVertical = rememberScrollState(0)
val stateHorizontal = rememberScrollState(0)
Box(
modifier = Modifier
.fillMaxSize()
.verticalScroll(stateVertical)
.padding(end = 12.dp, bottom = 12.dp)
.horizontalScroll(stateHorizontal)
) {
Column {
for (item in 0..30) {
TextBox("Item #$item")
if (item < 30) {
Spacer(modifier = Modifier.height(5.dp))
}
}
}
}
VerticalScrollbar(
modifier = Modifier.align(Alignment.CenterEnd)
.fillMaxHeight(),
adapter = rememberScrollbarAdapter(stateVertical)
)
HorizontalScrollbar(
modifier = Modifier.align(Alignment.BottomStart)
.fillMaxWidth()
.padding(end = 12.dp),
adapter = rememberScrollbarAdapter(stateHorizontal)
)
}
}
@Composable
fun TextBox(text: String = "Item") {
Box(
modifier = Modifier.height(32.dp)
.width(400.dp)
.background(color = Color(0, 0, 0, 20))
.padding(start = 10.dp),
contentAlignment = Alignment.CenterStart
) {
Text(text = text)
}
}
You can move scrollbars by dragging the bars and using the mouse wheel or the touchpad. To move horizontal scrollbars with the mouse, side-click the wheel or hold down Shift .
You can also use scrollbars with lazy scrollable components such as LazyColumn
and LazyRow
. Lazy components are much more efficient when you expect a lot of items in the list since they only compose the items as they're needed.
import androidx.compose.foundation.VerticalScrollbar
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.foundation.rememberScrollbarAdapter
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.Window
import androidx.compose.ui.window.application
import androidx.compose.ui.window.rememberWindowState
fun main() = application {
Window(
onCloseRequest = ::exitApplication,
title = "Scrollbars",
state = rememberWindowState(width = 300.dp, height = 310.dp)
) {
LazyScrollable()
}
}
@Composable
fun LazyScrollable() {
Box(
modifier = Modifier.fillMaxSize()
.background(color = Color(180, 180, 180))
.padding(10.dp)
) {
val state = rememberLazyListState()
LazyColumn(Modifier.fillMaxSize().padding(end = 12.dp), state) {
items(1000) { x ->
TextBox("Item #$x")
Spacer(modifier = Modifier.height(5.dp))
}
}
VerticalScrollbar(
modifier = Modifier.align(Alignment.CenterEnd).fillMaxHeight(),
adapter = rememberScrollbarAdapter(
scrollState = state
)
)
}
}
@Composable
fun TextBox(text: String = "Item") {
Box(
modifier = Modifier.height(32.dp)
.fillMaxWidth()
.background(color = Color(0, 0, 0, 20))
.padding(start = 10.dp),
contentAlignment = Alignment.CenterStart
) {
Text(text = text)
}
}
Last modified: 01 October 2024