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