Use constrained LazyVerticalGrid with calculated height for more than 20 images for performance reasons

added vertical spacing for some padding
Fixing scrollable gallery issue
This commit is contained in:
davotoula
2025-09-11 21:01:12 +02:00
parent f092326dcd
commit 8cb9d13567
@@ -27,11 +27,18 @@ import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.aspectRatio import androidx.compose.foundation.layout.aspectRatio
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.grid.GridCells
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
import androidx.compose.foundation.lazy.grid.items
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.unit.dp
import com.vitorpamplona.amethyst.commons.richtext.MediaUrlImage import com.vitorpamplona.amethyst.commons.richtext.MediaUrlImage
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
import com.vitorpamplona.amethyst.ui.theme.Size10dp
import com.vitorpamplona.amethyst.ui.theme.Size5dp import com.vitorpamplona.amethyst.ui.theme.Size5dp
import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.ImmutableList
@@ -62,56 +69,59 @@ fun ImageGallery(
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
roundedCorner: Boolean = true, roundedCorner: Boolean = true,
) { ) {
when { // Add vertical padding around the entire gallery for better text separation
images.isEmpty() -> { Column(modifier = modifier.padding(vertical = Size10dp)) {
// No images to display when {
} images.isEmpty() -> {
images.size == 1 -> { // No images to display
// Single image - display full width }
GalleryImage( images.size == 1 -> {
image = images.first(), // Single image - display full width
allImages = images, GalleryImage(
modifier = modifier.fillMaxWidth(), image = images.first(),
roundedCorner = roundedCorner, allImages = images,
contentScale = ContentScale.FillWidth, modifier = Modifier.fillMaxWidth(),
accountViewModel = accountViewModel, roundedCorner = roundedCorner,
) contentScale = ContentScale.FillWidth,
} accountViewModel = accountViewModel,
images.size == 2 -> { )
// Two images - side by side in 4:3 ratio }
TwoImageGallery( images.size == 2 -> {
images = images, // Two images - side by side in 4:3 ratio
accountViewModel = accountViewModel, TwoImageGallery(
roundedCorner = roundedCorner, images = images,
modifier = modifier, accountViewModel = accountViewModel,
) roundedCorner = roundedCorner,
} modifier = Modifier,
images.size == 3 -> { )
// Three images - one large, two small }
ThreeImageGallery( images.size == 3 -> {
images = images, // Three images - one large, two small
accountViewModel = accountViewModel, ThreeImageGallery(
roundedCorner = roundedCorner, images = images,
modifier = modifier, accountViewModel = accountViewModel,
) roundedCorner = roundedCorner,
} modifier = Modifier,
images.size == 4 -> { )
// Four images - 2x2 grid }
FourImageGallery( images.size == 4 -> {
images = images, // Four images - 2x2 grid
accountViewModel = accountViewModel, FourImageGallery(
roundedCorner = roundedCorner, images = images,
modifier = modifier, accountViewModel = accountViewModel,
) roundedCorner = roundedCorner,
} modifier = Modifier,
else -> { )
// Many images - use staggered grid with 4:3 ratio }
ManyImageGallery( else -> {
images = images, // Many images - use staggered grid with 4:3 ratio
accountViewModel = accountViewModel, ManyImageGallery(
roundedCorner = roundedCorner, images = images,
modifier = modifier, accountViewModel = accountViewModel,
) roundedCorner = roundedCorner,
modifier = Modifier,
)
}
} }
} }
} }
@@ -227,34 +237,62 @@ private fun ManyImageGallery(
else -> 4 // 4 columns for 10+ images else -> 4 // 4 columns for 10+ images
} }
val rows = (images.size + columns - 1) / columns // Ceiling division if (images.size <= 20) {
// For smaller sets, use non-lazy Column/Row approach (simpler, no constraint issues)
val rows = (images.size + columns - 1) / columns // Ceiling division
Column( Column(
modifier = modifier.aspectRatio(4f / 3f), modifier = modifier,
verticalArrangement = Arrangement.spacedBy(Size5dp), verticalArrangement = Arrangement.spacedBy(Size5dp),
) { ) {
repeat(rows) { rowIndex -> repeat(rows) { rowIndex ->
Row( Row(
modifier = Modifier.weight(1f).fillMaxWidth(), modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.spacedBy(Size5dp), horizontalArrangement = Arrangement.spacedBy(Size5dp),
) { ) {
repeat(columns) { colIndex -> repeat(columns) { colIndex ->
val imageIndex = rowIndex * columns + colIndex val imageIndex = rowIndex * columns + colIndex
if (imageIndex < images.size) { if (imageIndex < images.size) {
GalleryImage( GalleryImage(
image = images[imageIndex], image = images[imageIndex],
allImages = images, allImages = images,
modifier = Modifier.weight(1f).fillMaxSize(), modifier = Modifier.weight(1f).aspectRatio(1f),
roundedCorner = roundedCorner, roundedCorner = roundedCorner,
contentScale = ContentScale.Crop, contentScale = ContentScale.Crop,
accountViewModel = accountViewModel, accountViewModel = accountViewModel,
) )
} else { } else {
// Empty space for incomplete rows // Empty space for incomplete rows
Box(modifier = Modifier.weight(1f)) Box(modifier = Modifier.weight(1f))
}
} }
} }
} }
} }
} else {
// For larger sets, use LazyVerticalGrid with explicit height constraint
val rows = (images.size + columns - 1) / columns
// Calculate height: (image height + spacing) * rows - last spacing
// Assume square images with 5dp spacing
val gridHeight = (100 * rows + 5 * (rows - 1)).dp
LazyVerticalGrid(
columns = GridCells.Fixed(columns),
modifier = modifier.height(gridHeight), // Explicit height constraint
verticalArrangement = Arrangement.spacedBy(Size5dp),
horizontalArrangement = Arrangement.spacedBy(Size5dp),
userScrollEnabled = false,
) {
items(images) { image ->
GalleryImage(
image = image,
allImages = images,
modifier = Modifier.aspectRatio(1f),
roundedCorner = roundedCorner,
contentScale = ContentScale.Crop,
accountViewModel = accountViewModel,
)
}
}
} }
} }