// Coil
implementation "io.coil-kt:coil-compose:1.4.0"
Previously I used the coil together with Google's accompanist
, but when I migrate to the new version of the coil as the documentation suggests I'm having problems with the target
method:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.pokedex, PID: 13502
java.lang.IllegalArgumentException: request.target must be null.
at coil.compose.ImagePainterKt.rememberImagePainter(ImagePainter.kt:94)
...
When browsing the internal code of ImagePainter
(coil class) you can see that the target
method really needs to be null for some reason:
@Composable
fun rememberImagePainter(
request: ImageRequest,
imageLoader: ImageLoader,
onExecute: ExecuteCallback = ExecuteCallback.Default,
): ImagePainter {
requireSupportedData(request.data)
require(request.target == null) { "request.target must be null." }
...
Here's my component in jetpack compose (the image component is inside a column):
Image(
modifier = Modifier
.size(120.dp)
.align(Alignment.CenterHorizontally),
painter = rememberImagePainter(
data = entry.imageUrl,
builder = {
crossfade(true)
target {
viewModel.calcDominantColor(it) { color ->
dominantColor = color
}
}
transformations(CircleCropTransformation())
},
),
contentDescription = entry.pokemonName
)
I need the target method to do internal operations on my viewModel
based on the drawable
it passes as a parameter. Can someone help me?
In Coil 2.0.0 both AsyncImage
and rememberAsyncImagePainter
have onSuccess
callback parameter, using which you can get the drawable as follows:
AsyncImage(
model = imageURL,
contentDescription = null,
onSuccess = { success ->
val drawable = success.result.drawable
}
)
Coil 1.4.0 version:
This is intended behaviour since rememberImagePainter
sets the target
internally.
You can track the painter state, wait for the Success
and get the drawable
from it. Also use it with LaunchedEffect
to prevent re-calculations:
val painter = rememberImagePainter(
data = imageUrl,
builder = {
...
},
)
(painter.state as? ImagePainter.State.Success)
?.let { successState ->
LaunchedEffect(Unit) {
val drawable = successState.result.drawable
viewModel.calcDominantColor(drawable) { color ->
dominantColor = color
}
}
}
Image(
painter = painter,
contentDescription = "...",
modifier = Modifier
...
)