suresh
12/11/2020, 12:20 AMThread.UncaughtExceptionHandler
) and continue the recomposition or is this some kind of anti-pattern in compose?
Exception in thread "AWT-EventQueue-0 @coroutine#2" java.lang.IndexOutOfBoundsException: Index 5 out of bounds for length 5
at java.base/jdk.internal.util.Preconditions.outOfBounds(Preconditions.java:64)
at java.base/jdk.internal.util.Preconditions.outOfBoundsCheckIndex(Preconditions.java:70)
at java.base/jdk.internal.util.Preconditions.checkIndex(Preconditions.java:248)
at java.base/java.util.Objects.checkIndex(Objects.java:359)
at java.base/java.util.ArrayList.get(ArrayList.java:427)
at androidx.compose.material.TabRowKt$TabRow$1.invoke(TabRow.kt:117)
at androidx.compose.material.TabRowKt$TabRow$1.invoke(TabRow.kt)
Timo Drick
12/11/2020, 3:31 AMjim
12/11/2020, 5:32 AMTimo Drick
12/11/2020, 8:29 AMsealed class LoadingState<out T: Any> {
object Start: LoadingState<Nothing>()
object Loading: LoadingState<Nothing>()
class Error(val error: Exception): LoadingState<Nothing>()
class Success<T: Any>(val data: T): LoadingState<T>()
}
@Composable
fun <T: Any> loadingStateFor(vararg inputs: Any?, initBlock: () -> LoadingState<T> = { LoadingState.Start },
loadingBlock: suspend CoroutineScope.() -> T): LoadingState<T> {
var state by remember(*inputs) { mutableStateOf(initBlock()) }
if (state !is LoadingState.Success) {
LaunchedEffect(*inputs) {
val loadingSpinnerDelay = async {
delay(500)
state = LoadingState.Loading
}
state = try {
LoadingState.Success(loadingBlock())
} catch (err: Exception) {
LoadingState.Error(err)
} finally {
loadingSpinnerDelay.cancelAndJoin()
}
}
}
return state
}
Than you can use it in your composables like that:
val imageState = loadingStateFor(image) {
loadImageSizeFileCached(image.file, width)
}
Box(Modifier.fillMaxSize()) {
InitializedCrossfade(imageState) { state ->
when (state) {
is LoadingState.Loading -> LoadingBox()
is LoadingState.Success -> Image(
modifier = Modifier.fillMaxSize(),
bitmap = state.data,
contentScale = ContentScale.Fit
)
is LoadingState.Error -> ErrorBox(
message = "Error: ${state.error.message}",
onRetry = { retryCounter++ })
}
}
}
suresh
12/11/2020, 6:56 PM