Skip to content

Commit

Permalink
Merge pull request #46 from phucynwa/support_staggered_grid
Browse files Browse the repository at this point in the history
Support Staggered Grid
  • Loading branch information
nanihadesuka authored Nov 18, 2024
2 parents 04fa497 + af60969 commit de05fdd
Show file tree
Hide file tree
Showing 4 changed files with 519 additions and 2 deletions.
116 changes: 114 additions & 2 deletions app/src/main/java/my/nanihadesuka/lazycolumnscrollbar/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
import androidx.compose.foundation.lazy.grid.rememberLazyGridState
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.foundation.lazy.staggeredgrid.LazyHorizontalStaggeredGrid
import androidx.compose.foundation.lazy.staggeredgrid.LazyVerticalStaggeredGrid
import androidx.compose.foundation.lazy.staggeredgrid.StaggeredGridCells
import androidx.compose.foundation.lazy.staggeredgrid.items
import androidx.compose.foundation.lazy.staggeredgrid.rememberLazyStaggeredGridState
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
Expand All @@ -47,14 +52,17 @@ import androidx.compose.ui.unit.dp
import my.nanihadesuka.compose.ColumnScrollbar
import my.nanihadesuka.compose.LazyColumnScrollbar
import my.nanihadesuka.compose.LazyHorizontalGridScrollbar
import my.nanihadesuka.compose.LazyHorizontalStaggeredGridScrollbar
import my.nanihadesuka.compose.LazyVerticalGridScrollbar
import my.nanihadesuka.compose.LazyRowScrollbar
import my.nanihadesuka.compose.LazyVerticalStaggeredGridScrollbar
import my.nanihadesuka.compose.RowScrollbar
import my.nanihadesuka.compose.ScrollbarSelectionActionable
import my.nanihadesuka.compose.ScrollbarSelectionMode
import my.nanihadesuka.compose.ScrollbarLayoutSide
import my.nanihadesuka.compose.ScrollbarSettings
import my.nanihadesuka.lazycolumnscrollbar.ui.theme.LazyColumnScrollbarTheme
import kotlin.random.Random

class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
Expand All @@ -66,7 +74,8 @@ class MainActivity : ComponentActivity() {
enum class TypeTab {
Column, Row,
LazyColumn, LazyRow,
LazyVerticalGrid, LazyHorizontalGrid
LazyVerticalGrid, LazyHorizontalGrid,
LazyVerticalStaggeredGrid, LazyHorizontalStaggeredGrid
}

@OptIn(ExperimentalLayoutApi::class)
Expand Down Expand Up @@ -96,6 +105,8 @@ fun MainView() {
TypeTab.LazyRow -> LazyRowView()
TypeTab.LazyVerticalGrid -> LazyVerticalGridView()
TypeTab.LazyHorizontalGrid -> LazyHorizontalGridView()
TypeTab.LazyVerticalStaggeredGrid -> LazyVerticalStaggeredGridView()
TypeTab.LazyHorizontalStaggeredGrid -> LazyHorizontalStaggeredGridView()
}
}
}
Expand Down Expand Up @@ -313,6 +324,107 @@ fun LazyHorizontalGridView() {
}
}

@Composable
fun LazyVerticalStaggeredGridView() {
val items by rememberSaveable {
mutableStateOf(List(101) { it to Random.nextFloat() + 0.5F })
}

val lazyStaggeredGridState = rememberLazyStaggeredGridState()
Box(
modifier = Modifier
.padding(16.dp)
.border(width = 1.dp, MaterialTheme.colorScheme.primary)
.padding(1.dp)
) {
LazyVerticalStaggeredGridScrollbar(
state = lazyStaggeredGridState,
settings = ScrollbarSettings(
selectionMode = ScrollbarSelectionMode.Thumb,
alwaysShowScrollbar = true,
),
indicatorContent = { index, isThumbSelected ->
Indicator(text = "i:$index", isThumbSelected = isThumbSelected)
}
) {
LazyVerticalStaggeredGrid(
state = lazyStaggeredGridState,
columns = StaggeredGridCells.Adaptive(minSize = 128.dp),
verticalItemSpacing = 3.dp,
horizontalArrangement = Arrangement.spacedBy(3.dp),
) {
items(items, key = { it.first }) { (index, aspectRatio) ->
Surface(
tonalElevation = 3.dp,
modifier = Modifier.aspectRatio(aspectRatio),
color = Color.Yellow
) {
Text(
text = "Item $index",
modifier = Modifier
.padding(24.dp),
color = Color.Black
)

}
}
}
}

}
}

@Composable
fun LazyHorizontalStaggeredGridView() {
val items by rememberSaveable {
mutableStateOf(List(101) { it to Random.nextFloat() + 0.5F })
}

val lazyStaggeredGridState = rememberLazyStaggeredGridState()
Box(
modifier = Modifier
.padding(16.dp)
.border(width = 1.dp, MaterialTheme.colorScheme.primary)
.padding(1.dp)
) {
LazyHorizontalStaggeredGridScrollbar(
state = lazyStaggeredGridState,
settings = ScrollbarSettings(
selectionMode = ScrollbarSelectionMode.Thumb,
alwaysShowScrollbar = false
),
indicatorContent = { index, isThumbSelected ->
Indicator(text = "i:$index", isThumbSelected = isThumbSelected)
}
) {
LazyHorizontalStaggeredGrid(
state = lazyStaggeredGridState,
rows = StaggeredGridCells.Adaptive(minSize = 128.dp),
reverseLayout = true,
verticalArrangement = Arrangement.spacedBy(3.dp),
horizontalItemSpacing = 3.dp,
) {
items(items, key = { it.first }) { (index, aspectRatio) ->
Surface(
tonalElevation = 3.dp,
modifier = Modifier.aspectRatio(aspectRatio),
color = Color.Yellow
) {
Text(
text = "Item $index",
modifier = Modifier
.padding(24.dp),
color = Color.Black
)

}
}
}
}
}
}


@Composable
fun ColumnView() {
val listData = remember { (0..18).toList() }
Expand Down Expand Up @@ -419,4 +531,4 @@ fun Indicator(text: String, isThumbSelected: Boolean) {
.padding(12.dp)
)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package my.nanihadesuka.compose

import androidx.compose.foundation.gestures.Orientation
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.lazy.staggeredgrid.LazyStaggeredGridState
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import my.nanihadesuka.compose.controller.rememberLazyStaggeredGridStateController
import my.nanihadesuka.compose.generic.ElementScrollbar

@Composable
fun LazyHorizontalStaggeredGridScrollbar(
state: LazyStaggeredGridState,
modifier: Modifier = Modifier,
reverseLayout: Boolean = false,
settings: ScrollbarSettings = ScrollbarSettings.Default,
indicatorContent: (@Composable (index: Int, isThumbSelected: Boolean) -> Unit)? = null,
content: @Composable () -> Unit
) {
if (!settings.enabled) content()
else Box(modifier) {
content()
InternalLazyHorizontalGridScrollbar(
state = state,
reverseLayout = reverseLayout,
settings = settings,
indicatorContent = indicatorContent,
)
}
}

/**
* Use this variation if you want to place the scrollbar independently of the list position
*/
@Composable
fun InternalLazyHorizontalGridScrollbar(
state: LazyStaggeredGridState,
modifier: Modifier = Modifier,
reverseLayout: Boolean = false,
settings: ScrollbarSettings = ScrollbarSettings.Default,
indicatorContent: (@Composable (index: Int, isThumbSelected: Boolean) -> Unit)? = null,
) {
val controller = rememberLazyStaggeredGridStateController(
state = state,
reverseLayout = reverseLayout,
thumbMinLength = settings.thumbMinLength,
thumbMaxLength = settings.thumbMaxLength,
alwaysShowScrollBar = settings.alwaysShowScrollbar,
selectionMode = settings.selectionMode,
orientation = Orientation.Horizontal
)

ElementScrollbar(
orientation = Orientation.Horizontal,
stateController = controller,
modifier = modifier,
settings = settings,
indicatorContent = indicatorContent
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package my.nanihadesuka.compose

import androidx.compose.foundation.gestures.Orientation
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.lazy.staggeredgrid.LazyStaggeredGridState
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import my.nanihadesuka.compose.controller.rememberLazyStaggeredGridStateController
import my.nanihadesuka.compose.generic.ElementScrollbar

@Composable
fun LazyVerticalStaggeredGridScrollbar(
state: LazyStaggeredGridState,
modifier: Modifier = Modifier,
reverseLayout: Boolean = false,
settings: ScrollbarSettings = ScrollbarSettings.Default,
indicatorContent: (@Composable (index: Int, isThumbSelected: Boolean) -> Unit)? = null,
content: @Composable () -> Unit
) {
if (!settings.enabled) content()
else Box(modifier) {
content()
InternalLazyVerticalGridScrollbar(
state = state,
reverseLayout = reverseLayout,
settings = settings,
indicatorContent = indicatorContent,
)
}
}

/**
* Use this variation if you want to place the scrollbar independently of the list position
*/
@Composable
fun InternalLazyVerticalGridScrollbar(
state: LazyStaggeredGridState,
modifier: Modifier = Modifier,
reverseLayout: Boolean = false,
settings: ScrollbarSettings = ScrollbarSettings.Default,
indicatorContent: (@Composable (index: Int, isThumbSelected: Boolean) -> Unit)? = null,
) {
val controller = rememberLazyStaggeredGridStateController(
state = state,
reverseLayout = reverseLayout,
thumbMinLength = settings.thumbMinLength,
thumbMaxLength = settings.thumbMaxLength,
alwaysShowScrollBar = settings.alwaysShowScrollbar,
selectionMode = settings.selectionMode,
orientation = Orientation.Vertical
)

ElementScrollbar(
orientation = Orientation.Vertical,
stateController = controller,
modifier = modifier,
settings = settings,
indicatorContent = indicatorContent
)
}
Loading

0 comments on commit de05fdd

Please sign in to comment.