You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
249 lines
8.5 KiB
249 lines
8.5 KiB
4 years ago
|
# Scrollbar usage
|
||
|
|
||
|
## What is covered
|
||
|
|
||
4 years ago
|
In this tutorial, we will show you how to add scrollbars to scrollable lists using Compose for Desktop.
|
||
4 years ago
|
|
||
|
## Scrollbars applying
|
||
|
|
||
4 years ago
|
You can apply scrollbars to scrollable components. The scrollbar and scrollable components share a common state to synchronize with each other. For example, VerticalScrollbar can be attached to ScrollableColumn, and LazyColumnFor and HorizontalScrollbar can be attached to ScrollableRow and LazyRowFor.
|
||
4 years ago
|
|
||
|
```kotlin
|
||
|
import androidx.compose.desktop.Window
|
||
|
import androidx.compose.foundation.background
|
||
|
import androidx.compose.foundation.HorizontalScrollbar
|
||
|
import androidx.compose.foundation.layout.Box
|
||
|
import androidx.compose.foundation.layout.Column
|
||
|
import androidx.compose.foundation.layout.fillMaxHeight
|
||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||
|
import androidx.compose.foundation.layout.fillMaxSize
|
||
|
import androidx.compose.foundation.layout.height
|
||
|
import androidx.compose.foundation.layout.padding
|
||
|
import androidx.compose.foundation.layout.Spacer
|
||
|
import androidx.compose.foundation.layout.width
|
||
|
import androidx.compose.foundation.rememberScrollbarAdapter
|
||
|
import androidx.compose.foundation.rememberScrollState
|
||
|
import androidx.compose.foundation.ScrollableColumn
|
||
|
import androidx.compose.foundation.ScrollableRow
|
||
|
import androidx.compose.foundation.Text
|
||
|
import androidx.compose.foundation.VerticalScrollbar
|
||
|
import androidx.compose.runtime.Composable
|
||
|
import androidx.compose.ui.Alignment
|
||
|
import androidx.compose.ui.graphics.Color
|
||
|
import androidx.compose.ui.Modifier
|
||
|
import androidx.compose.ui.unit.dp
|
||
|
import androidx.compose.ui.unit.IntSize
|
||
|
|
||
|
fun main() {
|
||
|
Window(title = "Scrollbars", size = IntSize(250, 400)) {
|
||
|
Box(
|
||
|
modifier = Modifier.fillMaxSize()
|
||
|
.background(color = Color(180, 180, 180))
|
||
|
.padding(10.dp)
|
||
|
) {
|
||
|
val stateVertical = rememberScrollState(0f)
|
||
|
val stateHorizontal = rememberScrollState(0f)
|
||
|
|
||
|
ScrollableColumn(
|
||
|
modifier = Modifier.fillMaxSize()
|
||
|
.padding(end = 12.dp, bottom = 12.dp),
|
||
|
scrollState = stateVertical
|
||
|
) {
|
||
|
ScrollableRow(scrollState = stateHorizontal) {
|
||
|
Column {
|
||
|
for (item in 0..30) {
|
||
|
TextBox("Item in ScrollableColumn #$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),
|
||
|
alignment = Alignment.CenterStart
|
||
|
) {
|
||
|
Text(text = text)
|
||
|
}
|
||
|
}
|
||
|
```
|
||
|
|
||
|
![Scrollbars](scrollbars.gif)
|
||
|
|
||
|
## Lazy scrollable components with Scrollbar
|
||
|
|
||
|
You can use scrollbars with lazy scrollable components, for example, LazyColumn.
|
||
|
|
||
|
```kotlin
|
||
|
import androidx.compose.desktop.Window
|
||
|
import androidx.compose.foundation.background
|
||
|
import androidx.compose.foundation.ExperimentalFoundationApi
|
||
|
import androidx.compose.foundation.layout.Box
|
||
|
import androidx.compose.foundation.layout.fillMaxHeight
|
||
|
import androidx.compose.foundation.layout.fillMaxSize
|
||
|
import androidx.compose.foundation.layout.height
|
||
|
import androidx.compose.foundation.layout.padding
|
||
|
import androidx.compose.foundation.layout.Spacer
|
||
|
import androidx.compose.foundation.lazy.ExperimentalLazyDsl
|
||
|
import androidx.compose.foundation.lazy.LazyColumn
|
||
|
import androidx.compose.foundation.lazy.rememberLazyListState
|
||
|
import androidx.compose.foundation.rememberScrollbarAdapter
|
||
|
import androidx.compose.foundation.Text
|
||
|
import androidx.compose.foundation.VerticalScrollbar
|
||
|
import androidx.compose.runtime.Composable
|
||
|
import androidx.compose.ui.Alignment
|
||
|
import androidx.compose.ui.graphics.Color
|
||
|
import androidx.compose.ui.Modifier
|
||
|
import androidx.compose.ui.unit.dp
|
||
|
import androidx.compose.ui.unit.IntSize
|
||
|
|
||
|
fun main() {
|
||
|
Window(title = "Scrollbars", size = IntSize(250, 400)) {
|
||
|
LazyScrollable()
|
||
|
}
|
||
|
}
|
||
|
|
||
|
@OptIn(ExperimentalLazyDsl::class, ExperimentalFoundationApi::class)
|
||
|
@Composable
|
||
|
fun LazyScrollable() {
|
||
|
Box(
|
||
|
modifier = Modifier.fillMaxSize()
|
||
|
.background(color = Color(180, 180, 180))
|
||
|
.padding(10.dp)
|
||
|
) {
|
||
|
|
||
|
val state = rememberLazyListState()
|
||
|
val itemCount = 1000
|
||
|
|
||
|
LazyColumn(Modifier.fillMaxSize().padding(end = 12.dp), state) {
|
||
|
items((1..itemCount).toList()) { x ->
|
||
|
TextBox("Item in ScrollableColumn #$x")
|
||
|
Spacer(modifier = Modifier.height(5.dp))
|
||
|
}
|
||
|
}
|
||
|
VerticalScrollbar(
|
||
|
modifier = Modifier.align(Alignment.CenterEnd).fillMaxHeight(),
|
||
|
adapter = rememberScrollbarAdapter(
|
||
|
scrollState = state,
|
||
|
itemCount = itemCount,
|
||
|
averageItemSize = 37.dp // TextBox height + Spacer height
|
||
|
)
|
||
|
)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
@Composable
|
||
|
fun TextBox(text: String = "Item") {
|
||
|
Box(
|
||
|
modifier = Modifier.height(32.dp)
|
||
|
.fillMaxWidth()
|
||
|
.background(color = Color(0, 0, 0, 20))
|
||
|
.padding(start = 10.dp),
|
||
|
alignment = Alignment.CenterStart
|
||
|
) {
|
||
|
Text(text = text)
|
||
|
}
|
||
|
}
|
||
|
```
|
||
|
|
||
|
![Lazy component](lazy_scrollbar.gif)
|
||
|
|
||
|
## Theme applying
|
||
|
|
||
4 years ago
|
Scrollbars support themes to change their appearance. The example below shows how to use the DesktopTheme appearance for the scrollbar.
|
||
4 years ago
|
|
||
|
```kotlin
|
||
|
import androidx.compose.desktop.DesktopTheme
|
||
|
import androidx.compose.desktop.Window
|
||
|
import androidx.compose.foundation.background
|
||
|
import androidx.compose.foundation.layout.Box
|
||
|
import androidx.compose.foundation.layout.fillMaxHeight
|
||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||
|
import androidx.compose.foundation.layout.fillMaxSize
|
||
|
import androidx.compose.foundation.layout.height
|
||
|
import androidx.compose.foundation.layout.padding
|
||
|
import androidx.compose.foundation.layout.Spacer
|
||
|
import androidx.compose.foundation.layout.width
|
||
|
import androidx.compose.foundation.rememberScrollbarAdapter
|
||
|
import androidx.compose.foundation.rememberScrollState
|
||
|
import androidx.compose.foundation.ScrollableColumn
|
||
|
import androidx.compose.foundation.Text
|
||
|
import androidx.compose.foundation.VerticalScrollbar
|
||
|
import androidx.compose.material.MaterialTheme
|
||
|
import androidx.compose.runtime.Composable
|
||
|
import androidx.compose.ui.Alignment
|
||
|
import androidx.compose.ui.graphics.Color
|
||
|
import androidx.compose.ui.Modifier
|
||
|
import androidx.compose.ui.unit.dp
|
||
|
import androidx.compose.ui.unit.IntSize
|
||
|
|
||
|
fun main() {
|
||
|
Window(title = "Scrollbars", size = IntSize(280, 400)) {
|
||
|
MaterialTheme {
|
||
|
DesktopTheme {
|
||
|
Box(
|
||
|
modifier = Modifier.fillMaxSize()
|
||
|
.background(color = Color(180, 180, 180))
|
||
|
.padding(10.dp)
|
||
|
) {
|
||
|
val state = rememberScrollState(0f)
|
||
|
|
||
|
ScrollableColumn(
|
||
|
modifier = Modifier.fillMaxSize().padding(end = 12.dp),
|
||
|
scrollState = state
|
||
|
) {
|
||
|
for (item in 0..30) {
|
||
|
TextBox("Item in ScrollableColumn #$item")
|
||
|
if (item < 30) {
|
||
|
Spacer(modifier = Modifier.height(5.dp))
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
VerticalScrollbar(
|
||
|
modifier = Modifier.align(Alignment.CenterEnd)
|
||
|
.fillMaxHeight(),
|
||
|
adapter = rememberScrollbarAdapter(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),
|
||
|
alignment = Alignment.CenterStart
|
||
|
) {
|
||
|
Text(text = text)
|
||
|
}
|
||
|
}
|
||
|
```
|
||
|
|
||
|
![Themed scrollbar](themed_scrollbar.gif)
|