From d60cbe4678c809893cd1fe549a88b58daa015910 Mon Sep 17 00:00:00 2001 From: Wynd Date: Sun, 1 Mar 2026 17:29:36 +0200 Subject: [PATCH] Image caching and using normal grid instead of staggered --- .../java/xyz/pixelatedw/recipe/data/Recipe.kt | 14 ++++- .../recipe/ui/components/MainScreen.kt | 54 ++++++++++--------- .../recipe/ui/components/RecipePreview.kt | 9 ++-- 3 files changed, 44 insertions(+), 33 deletions(-) diff --git a/app/src/main/java/xyz/pixelatedw/recipe/data/Recipe.kt b/app/src/main/java/xyz/pixelatedw/recipe/data/Recipe.kt index 7dd0518..5eec5bb 100644 --- a/app/src/main/java/xyz/pixelatedw/recipe/data/Recipe.kt +++ b/app/src/main/java/xyz/pixelatedw/recipe/data/Recipe.kt @@ -3,8 +3,8 @@ package xyz.pixelatedw.recipe.data import android.content.Context import android.graphics.Bitmap import android.graphics.BitmapFactory +import android.widget.ImageView import androidx.core.net.toUri -import androidx.documentfile.provider.DocumentFile import androidx.room.Dao import androidx.room.Delete import androidx.room.Entity @@ -17,6 +17,9 @@ import com.google.gson.Gson import com.google.gson.reflect.TypeToken import java.io.File + +private val imagesCache: HashMap = hashMapOf() + @Entity data class Recipe( @PrimaryKey @@ -33,10 +36,17 @@ data class Recipe( fun showImage(ctx: Context, idx: Int): Bitmap? { val img = this.pics.getOrNull(idx) if (img != null) { + val cachedImage = imagesCache[img] + if (cachedImage != null) { + return cachedImage + } + val file = File(ctx.filesDir, img) if (file.exists()) { ctx.contentResolver.openInputStream(file.toUri()).use { - return BitmapFactory.decodeStream(it) + val bitmapData = BitmapFactory.decodeStream(it) + imagesCache[img] = bitmapData + return bitmapData } } } diff --git a/app/src/main/java/xyz/pixelatedw/recipe/ui/components/MainScreen.kt b/app/src/main/java/xyz/pixelatedw/recipe/ui/components/MainScreen.kt index b0ef4a2..59ecd6a 100644 --- a/app/src/main/java/xyz/pixelatedw/recipe/ui/components/MainScreen.kt +++ b/app/src/main/java/xyz/pixelatedw/recipe/ui/components/MainScreen.kt @@ -7,12 +7,9 @@ import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.foundation.lazy.items -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.lazy.grid.GridCells +import androidx.compose.foundation.lazy.grid.LazyVerticalGrid +import androidx.compose.foundation.lazy.grid.rememberLazyGridState import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Delete import androidx.compose.material.icons.filled.Settings @@ -61,7 +58,7 @@ fun MainScreen(ctx: MainActivity, padding: PaddingValues, view: RecipesView) { var openTagFilterDialog by remember { mutableStateOf(false) } var selectedEntries by remember { mutableStateOf(listOf()) } - val gridState = rememberLazyStaggeredGridState() + val gridState = rememberLazyGridState() NavHost( navController = navController, @@ -136,29 +133,34 @@ fun MainScreen(ctx: MainActivity, padding: PaddingValues, view: RecipesView) { ) } } - LazyVerticalStaggeredGrid( - columns = StaggeredGridCells.Fixed(3), + LazyVerticalGrid( + columns = GridCells.Fixed(3), modifier = Modifier.fillMaxSize(), horizontalArrangement = Arrangement.spacedBy(8.dp), - verticalItemSpacing = 8.dp, + verticalArrangement = Arrangement.spacedBy(8.dp), state = gridState, ) { - items(activeRecipes) { entry -> - val isSelected = selectedEntries.contains(entry) - RecipePreview(entry, isSelected, onClick = { - view.setActive(entry) - navController.navigate("info") - }, onSelected = { flag -> - selectedEntries = - selectedEntries.toMutableList().apply { - if (flag) { - add(entry) - } else { - remove(entry) - } - }.toList() - }) - } + items( + count = activeRecipes.size, + key = { activeRecipes[it].recipe.title }, + itemContent = { entryId -> + val entry = activeRecipes[entryId] + val isSelected = selectedEntries.contains(entry) + RecipePreview(entry, isSelected, onClick = { + view.setActive(entry) + navController.navigate("info") + }, onSelected = { flag -> + selectedEntries = + selectedEntries.toMutableList().apply { + if (flag) { + add(entry) + } else { + remove(entry) + } + }.toList() + }) + } + ) } } diff --git a/app/src/main/java/xyz/pixelatedw/recipe/ui/components/RecipePreview.kt b/app/src/main/java/xyz/pixelatedw/recipe/ui/components/RecipePreview.kt index e852f48..3ba665d 100644 --- a/app/src/main/java/xyz/pixelatedw/recipe/ui/components/RecipePreview.kt +++ b/app/src/main/java/xyz/pixelatedw/recipe/ui/components/RecipePreview.kt @@ -15,6 +15,7 @@ import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect @@ -66,11 +67,12 @@ fun RecipePreview( ) { Row( horizontalArrangement = Arrangement.Center, - modifier = Modifier.weight(0.7f) + modifier = Modifier.fillMaxWidth().weight(0.7f) ) { AnimatedContent( displayImageId, label = "Recipe Preview", + modifier = Modifier.fillMaxSize(), transitionSpec = { fadeIn(animationSpec = tween(500)) .togetherWith(fadeOut(animationSpec = tween(500))) @@ -82,14 +84,12 @@ fun RecipePreview( bitmap = displayImage.asImageBitmap(), contentDescription = "Recipe image", contentScale = ContentScale.FillHeight, - modifier = Modifier.fillMaxSize(), ) } else { Image( bitmap = ImageBitmap.imageResource(R.drawable.missing_image), contentDescription = "Missing recipe image", - contentScale = ContentScale.FillWidth, - modifier = Modifier.fillMaxSize(), + contentScale = ContentScale.FillHeight, ) } } @@ -104,7 +104,6 @@ fun RecipePreview( modifier = Modifier.fillMaxWidth(), style = TextStyle( textAlign = TextAlign.Center, -// fontSize = 7.em, ) ) }