coil: Reload image after a failed load in Jetpack Compose
Is your feature request related to a problem? Please describe.
val painter = rememberImagePainter(url)
Image(
modifier = Modifier.fillMaxSize(),
painter = painter,
contentDescription = null,
contentScale = ContentScale.Fit
)
when (val state = painter.state) {
is ImagePainter.State.Error -> {
TextButton(onClick = { }) { Text("retry") }
}
}
After a failed load, the user should be able to reload the image via the retry button.
Describe the solution you’d like
It is better to provide reload method, but it seems that setting request in ImagePainter to public would also work.
About this issue
- Original URL
- State: open
- Created 3 years ago
- Reactions: 15
- Comments: 16 (4 by maintainers)
Still figuring out a good public API for this, but if you need this today you can force retry by changing a parameter:
Currently, I’m thinking the public API should be something like this, but let me know what you think!
Hi folks, quick update on this. This is definitely something I want to address properly in Coil 3.0. Ideally, we can kill two birds with one stone and hoist
AsyncImagePainterso that way users can also observe its other properties (likestateorrequest). For example:There are some implementation details that might cause this to not work in practice, but it’s the API I’d like!
In the meantime for 2.x I’d continue to use this solution, which isn’t ideal, but should force the request to restart.
Only works for me if
.setParameter("retry_hash", retryHash, memoryCacheKey = null)in @colinrtwhite 's solution is used without thememoryCacheKeyargument, thus.setParameter("retry_hash", retryHash).Also if
retryHashis a Boolean, the model toggles between its first two instances, so it does need to have a range.would be nice to add a support for this
I see. In that case, I would prefer code like this:
I don’t think the retry function should be used outside of
AsyncImageScope. But some global components likeBottomSheetdo cause this situation (I personally take it as a design mistake). In that case, a simple lambda should be enough:val retryHandle = { painter.retry() }If someone needs more complex control logic (like refreshing multiple images at once), he can use a
Flow<RefreshEvent>and collect it insideAsyncImageScope.Anyway, I prefer the direct api, mainly because
focusRequestermessed up my code.Thanks! I’ll try it later.
The api is indeed a problem. Your example is very similar to
focusRequester. I’m ok with it. But since there must be an ImagePainter object here, I think it would be simpler to have an ImagePainter with a retry method.