androidandroid-jetpack-composecoil

PainterResource throws IllegalArgumentException: Only VectorDrawables and rasterized asset types are supported


I am working on a Jetpack Project which downloads an image from API using Coil Library.

I have confirmed that valid image URLs and related data are being returned from the API call successfully. I am able to view the image on my browser using the returned URL.

This is my Image Composable:

@Composable
fun AstroPhoto(picture: AstroPicture) {

    val imgUrl = picture.url.toUri()
            .buildUpon()
            .scheme("https")
            .build()
    
    AsyncImage(model = ImageRequest.Builder(LocalContext.current)
            .data(imgUrl)
            .size(Size.ORIGINAL)
            .crossfade(true).build(),

            placeholder = painterResource(R.drawable.loading_animation),
            contentDescription = picture.title,
            contentScale = ContentScale.Crop,
    )
}

I call the above image composable in a Lazy Column:

....
 Box( ... ) {
            
           LazyColumn(content = {
               
               items(state.astroPictures) {
               
                AstroPhoto(picture = it)
            } })
            
        }

This is the exception at I am getting:

FATAL EXCEPTION: main Process: com.uxstate, PID: 31790 java.lang.IllegalArgumentException: Only VectorDrawables and rasterized asset types are supported ex. PNG, JPG at androidx.compose.ui.res.PainterResources_androidKt.loadVectorResource(PainterResources.android.kt:93)

I am on compose_version = '1.1.1' working with kotlin_version = '1.6.10'. My coil version is "io.coil-kt:coil-compose:2.1.0" and compileSdk 32 and AS Chipmunk. Source code can be found here.

I have checked the docs and searched online but cannot resolve the error. Please help me to go about the error, Thanks.


Solution

  • This appears to be a Jetpack Compose bug

    For the time being I've been able to fix this issue in my own project by using an AndroidView to render an ImageView.

    In the case of you needing to asynchronously load images, you could render a Glide imageview or something similar

    fun AppImage(
        modifier: Modifier = Modifier,
        @DrawableRes resource: Int,
        colorFilter: ColorFilter? = null
    ) {
        AndroidView(
            modifier = modifier,
            factory = { context ->
            ImageView(context).apply {
                setImageResource(resource)
                setColorFilter(colorFilter?.asAndroidColorFilter())
            }
        },
            update = {
                it.setImageResource(resource)
                it.colorFilter = colorFilter?.asAndroidColorFilter()
            }
        )
    }