Browse Source

Components. AnimatedImage. Fix 'load' function. (#2043)

Passed to 'load' lambda can change every recomposition (it depends on variables which are captured inside it)
pull/2047/head
Igor Demin 3 years ago committed by GitHub
parent
commit
4ff361bd62
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 15
      components/AnimatedImage/demo/src/jvmMain/kotlin/org/jetbrains/compose/animatedimage/demo/Main.kt
  2. 38
      components/resources/library/src/commonMain/kotlin/org/jetbrains/compose/resources/LoadState.kt

15
components/AnimatedImage/demo/src/jvmMain/kotlin/org/jetbrains/compose/animatedimage/demo/Main.kt

@ -5,6 +5,7 @@ import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.size
import androidx.compose.material.CircularProgressIndicator
import androidx.compose.material.Text
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.ImageBitmap
import androidx.compose.ui.unit.dp
@ -16,16 +17,14 @@ import org.jetbrains.compose.resources.LoadState
import org.jetbrains.compose.resources.load
import org.jetbrains.compose.resources.loadOrNull
fun main() = singleWindowApplication {
val url =
private val url =
"https://raw.githubusercontent.com/JetBrains/skija/ccf303ebcf926e5ef000fc42d1a6b5b7f1e0b2b5/examples/scenes/images/codecs/animated.gif"
// Load an image async
val animatedImage =
load { loadAnimatedImage(url) } // use "load { loadResourceAnimatedImage(url) }" for resources
fun main() = singleWindowApplication {
Column {
when (animatedImage) {
// Load an image async
// use "load { loadResourceAnimatedImage(url) }" for resources
when (val animatedImage = load { loadAnimatedImage(url) }) {
is LoadState.Success -> Image(
bitmap = animatedImage.value.animate(),
contentDescription = null,
@ -34,7 +33,6 @@ fun main() = singleWindowApplication {
is LoadState.Error -> Text("Error!")
}
Column {
Image(
loadOrNull { loadAnimatedImage(url) }?.animate() ?: ImageBitmap.Blank,
contentDescription = null,
@ -42,4 +40,3 @@ fun main() = singleWindowApplication {
)
}
}
}

38
components/resources/library/src/commonMain/kotlin/org/jetbrains/compose/resources/LoadState.kt

@ -15,8 +15,38 @@ sealed class LoadState<T> {
@Composable
fun <T> load(load: suspend () -> T): LoadState<T> {
var state: LoadState<T> by remember(load) { mutableStateOf(LoadState.Loading()) }
LaunchedEffect(load) {
return load(Unit, load)
}
@Composable
fun <T: Any> loadOrNull(load: suspend () -> T): T? {
return loadOrNull(Unit, load)
}
@Composable
fun <T> load(key1: Any?, load: suspend () -> T): LoadState<T> {
return load(key1, Unit, load)
}
@Composable
fun <T: Any> loadOrNull(key1: Any?, load: suspend () -> T): T? {
return loadOrNull(key1, Unit, load)
}
@Composable
fun <T> load(key1: Any?, key2: Any?, load: suspend () -> T): LoadState<T> {
return load(key1, key2, Unit, load)
}
@Composable
fun <T: Any> loadOrNull(key1: Any?, key2: Any?, load: suspend () -> T): T? {
return loadOrNull(key1, key2, Unit, load)
}
@Composable
fun <T> load(key1: Any?, key2: Any?, key3: Any?, load: suspend () -> T): LoadState<T> {
var state: LoadState<T> by remember(key1, key2, key3) { mutableStateOf(LoadState.Loading()) }
LaunchedEffect(key1, key2, key3) {
state = try {
LoadState.Success(load())
} catch (e: Exception) {
@ -27,7 +57,7 @@ fun <T> load(load: suspend () -> T): LoadState<T> {
}
@Composable
fun <T: Any> loadOrNull(load: suspend () -> T): T? {
val state = load(load)
fun <T: Any> loadOrNull(key1: Any?, key2: Any?, key3: Any?, load: suspend () -> T): T? {
val state = load(key1, key2, key3, load)
return (state as? LoadState.Success<T>)?.value
}
Loading…
Cancel
Save