My screen has a horizontal gallery at the top (LazyRow
) and beneath it has a grid of 8 buttons that can be scrolled (LazyGrid
).
Due to the layout the grid when scrolled doesn't affect the gallery which makes sense.
What I'd like to do however is for the entire screen to scroll when I scroll the menu, as I scroll up, the gallery should disappear out of view.
I am thinking that the only way that I can get this done is to change the root Column
into a LazyColumn
.
Is there a better way? Should I be using a surface instead?
I did try adding the following to the Column's Modifier but that made no difference since my grid is itself scrollable.
.scrollable(state = scrollState, orientation = Orientation.Vertical)
This is my current code:
@Composable
fun MainMenuScreen(imageGalleryPaths: List<String>, menuItemList: List<MenuItem>) {
Column(
modifier = Modifier
.background(
brush = Brush.verticalGradient(
colors = listOf(
MainMenuScreenBackgroundColorGradientStart,
MainMenuScreenBackgroundColorGradientEnd
)
)
)
) {
HorizontalImageGallery(assetPaths = imageGalleryPaths)
VerticalGridButtons(menuItems = menuItemList)
}
}
@Composable
fun HorizontalImageGallery(assetPaths: List<String>) {
LazyRow(modifier = Modifier.height(160.dp)) {
items(assetPaths) { assetPath ->
GalleryCard(assetPath)
}
}
}
@Composable
fun VerticalGridButtons(menuItems: List<MenuItem>) {
LazyVerticalGrid(
columns = GridCells.Fixed(2),
contentPadding = PaddingValues(8.dp)
) {
items(menuItems) { menuItem ->
MenuItem(menuItem)
}
}
}
@Composable
fun GalleryCard(model: String) {
Card(modifier = Modifier
.padding(start = 0.dp, top = 10.dp, end = 10.dp, bottom = 10.dp)
.fillMaxSize(),
elevation = CardDefaults.cardElevation(defaultElevation = 8.dp),
shape = RoundedCornerShape(8.dp)
) {
AsyncImage(
model = model,
contentDescription = "Porsche Gallery Image",
contentScale = ContentScale.FillBounds,
modifier = Modifier
.size(150.dp)
.padding(4.dp)
)
}
}
Any guidance would greatly be appreciated.
To rewrite your code in a minimal example, it can be like this.
@Composable
fun ScrollableScreenDemo() {
Column(
modifier = Modifier,
) {
HorizontalImageGallery()
VerticalGridButtons()
}
}
@Composable
fun HorizontalImageGallery() {
LazyRow {
items(30) {
Box(
modifier = Modifier
.padding(4.dp)
.size(30.dp)
.background(Color.LightGray),
)
}
}
}
@Composable
fun VerticalGridButtons() {
LazyVerticalGrid(
columns = GridCells.Fixed(2),
) {
items(100) {
Box(
modifier = Modifier
.padding(4.dp)
.size(30.dp)
.background(Color.DarkGray),
)
}
}
}
To scroll the whole screen it can be rewritten like this,
@Composable
fun ScrollableScreenDemo() {
VerticalGridButtons()
}
@Composable
fun HorizontalImageGallery() {
LazyRow {
items(30) {
Box(
modifier = Modifier
.padding(4.dp)
.size(30.dp)
.background(Color.LightGray),
)
}
}
}
@Composable
fun VerticalGridButtons() {
LazyVerticalGrid(
columns = GridCells.Fixed(2),
) {
item(
span = {
GridItemSpan(maxLineSpan)
},
) {
HorizontalImageGallery()
}
items(100) {
Box(
modifier = Modifier
.padding(4.dp)
.size(30.dp)
.background(Color.DarkGray),
)
}
}
}
Changes
Make the LazyVerticalGrid
the parent and have the HorizontalImageGallery
inside it with GridItemSpan(maxLineSpan)
.