fixing performance issue when loading large lists of images

This commit is contained in:
Adam Brown 2022-09-29 13:11:23 +01:00
parent 6f89c71300
commit 34e0415892

View File

@ -13,25 +13,19 @@ import androidx.compose.material3.Surface
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.material3.TextButton import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Brush import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.layout.onGloballyPositioned
import androidx.compose.ui.platform.LocalConfiguration import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.unit.IntSize
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import app.dapk.st.core.* import app.dapk.st.core.*
import app.dapk.st.core.components.CenteredLoading import app.dapk.st.core.components.CenteredLoading
import app.dapk.st.design.components.GenericError
import app.dapk.st.design.components.Route import app.dapk.st.design.components.Route
import app.dapk.st.design.components.Spider import app.dapk.st.design.components.Spider
import app.dapk.st.design.components.SpiderPage import app.dapk.st.design.components.SpiderPage
@ -222,10 +216,12 @@ fun ImageGalleryScreen(viewModel: ImageGalleryViewModel, onTopLevelBack: () -> U
@Composable @Composable
fun ImageGalleryFolders(state: ImageGalleryPage.Folders, onClick: (Folder) -> Unit) { fun ImageGalleryFolders(state: ImageGalleryPage.Folders, onClick: (Folder) -> Unit) {
var boxWidth by remember { mutableStateOf(IntSize.Zero) }
val localDensity = LocalDensity.current
val screenWidth = LocalConfiguration.current.screenWidthDp val screenWidth = LocalConfiguration.current.screenWidthDp
val gradient = Brush.verticalGradient(
colors = listOf(Color.Transparent, Color.Black.copy(alpha = 0.5f)),
)
when (val content = state.content) { when (val content = state.content) {
is Lce.Loading -> { is Lce.Loading -> {
CenteredLoading() CenteredLoading()
@ -242,11 +238,8 @@ fun ImageGalleryFolders(state: ImageGalleryPage.Folders, onClick: (Folder) -> Un
modifier = Modifier.fillMaxSize(), modifier = Modifier.fillMaxSize(),
) { ) {
items(content.value, key = { it.bucketId }) { items(content.value, key = { it.bucketId }) {
Box(modifier = Modifier.fillMaxWidth().padding(2.dp) Box(modifier = Modifier.fillMaxWidth().padding(2.dp).aspectRatio(1f)
.clickable { onClick(it) } .clickable { onClick(it) }) {
.onGloballyPositioned {
boxWidth = it.size
}) {
Image( Image(
painter = rememberAsyncImagePainter( painter = rememberAsyncImagePainter(
model = ImageRequest.Builder(LocalContext.current) model = ImageRequest.Builder(LocalContext.current)
@ -254,17 +247,11 @@ fun ImageGalleryFolders(state: ImageGalleryPage.Folders, onClick: (Folder) -> Un
.build(), .build(),
), ),
contentDescription = "123", contentDescription = "123",
modifier = Modifier.fillMaxWidth().height(with(localDensity) { boxWidth.width.toDp() }), modifier = Modifier.fillMaxSize(),
contentScale = ContentScale.Crop contentScale = ContentScale.Crop
) )
val gradient = Brush.verticalGradient( Box(modifier = Modifier.fillMaxWidth().fillMaxHeight(0.6f).background(gradient).align(Alignment.BottomStart))
colors = listOf(Color.Transparent, Color.Black.copy(alpha = 0.5f)),
startY = boxWidth.width.toFloat() * 0.5f,
endY = boxWidth.width.toFloat()
)
Box(modifier = Modifier.matchParentSize().background(gradient))
Row( Row(
modifier = Modifier.fillMaxWidth().align(Alignment.BottomStart).padding(4.dp), modifier = Modifier.fillMaxWidth().align(Alignment.BottomStart).padding(4.dp),
horizontalArrangement = Arrangement.SpaceBetween, horizontalArrangement = Arrangement.SpaceBetween,
@ -279,14 +266,12 @@ fun ImageGalleryFolders(state: ImageGalleryPage.Folders, onClick: (Folder) -> Un
} }
} }
is Lce.Error -> TODO() is Lce.Error -> GenericError { }
} }
} }
@Composable @Composable
fun ImageGalleryMedia(state: ImageGalleryPage.Files) { fun ImageGalleryMedia(state: ImageGalleryPage.Files) {
var boxWidth by remember { mutableStateOf(IntSize.Zero) }
val localDensity = LocalDensity.current
val screenWidth = LocalConfiguration.current.screenWidthDp val screenWidth = LocalConfiguration.current.screenWidthDp
Column { Column {
@ -299,15 +284,15 @@ fun ImageGalleryMedia(state: ImageGalleryPage.Files) {
is Lce.Loading -> { is Lce.Loading -> {
CenteredLoading() CenteredLoading()
} }
is Lce.Content -> { is Lce.Content -> {
LazyVerticalGrid( LazyVerticalGrid(
columns = GridCells.Fixed(columns), columns = GridCells.Fixed(columns),
modifier = Modifier.fillMaxSize(), modifier = Modifier.fillMaxSize(),
) { ) {
val modifier = Modifier.fillMaxWidth().padding(2.dp).aspectRatio(1f)
items(content.value, key = { it.id }) { items(content.value, key = { it.id }) {
Box(modifier = Modifier.fillMaxWidth().padding(2.dp).onGloballyPositioned { Box(modifier = modifier) {
boxWidth = it.size
}) {
Image( Image(
painter = rememberAsyncImagePainter( painter = rememberAsyncImagePainter(
model = ImageRequest.Builder(LocalContext.current) model = ImageRequest.Builder(LocalContext.current)
@ -316,7 +301,7 @@ fun ImageGalleryMedia(state: ImageGalleryPage.Files) {
.build(), .build(),
), ),
contentDescription = "123", contentDescription = "123",
modifier = Modifier.fillMaxWidth().height(with(localDensity) { boxWidth.width.toDp() }), modifier = Modifier.fillMaxWidth().fillMaxHeight(),
contentScale = ContentScale.Crop contentScale = ContentScale.Crop
) )
} }
@ -324,7 +309,7 @@ fun ImageGalleryMedia(state: ImageGalleryPage.Files) {
} }
} }
is Lce.Error -> TODO() is Lce.Error -> GenericError { }
} }
} }