Variable ImagePainter on Jetpack Compose
Asked Answered
P

2

8

I'm working on an Android app using Jetpack Compose 1.0.0 and I'm trying to make a composable that uses a nullable image URL string and, if it's null, it will show a placeholder with painterResource and, if it's not null, it will display the actual image using rememberImagePainter.

The way I was doing that was:

@Composable
fun VariableImagePainterExample (
    imageURL: String?
) {
    val painter = rememberCoilPainter(
        null,
        previewPlaceholder = R.drawable.ic_placeholder_user,
        fadeIn = true,
    )

    LaunchedEffect(imageURL) {
        painter.request = imageURL
    }

    Image(painter = painter, contentDescription = null)
}

Unfortunately, the rememberCoilPainter became deprecated from accompanist-coil and it's suggested now to use the rememberImagePainter. However, the ImagePainter.request can't be changed like above. I then tried the following code:

@Composable
fun VariableImagePainterExample (
    imageURL: String?
) {
    val painter = remember {
        mutableStateOf<ImagePainter>(painterResource(id = R.drawable.ic_placeholder_user))
    }

    LaunchedEffect(imageURL) {
        painter.value = rememberImagePainter(imageURL)
    }

    Image(painter = painter.value, contentDescription = null)
}

But this doesn't work because painterResource and rememberImagePainter must be used on the @Composable function. How can i achieve the same effect as before?

Piecework answered 6/8, 2021 at 18:17 Comment(0)
A
9

In Coil 2.0.0 both AsyncImage and rememberAsyncImagePainter have placeholder parameter that takes any other painter:

AsyncImage(
    model = imageURL,
    placeholder = painterResource(R.drawable.placeholder),
    contentDescription = null,
)

In Coil 1.4.0 you can use builder like this:

Image(
    rememberImagePainter(
        imageURL,
        builder = {
            placeholder(R.drawable.placeholder)
        }
    ),
    contentDescription = null,
)
Appositive answered 7/8, 2021 at 5:13 Comment(3)
Because the imageURL is nullable. At the first compose, the value would be null, until the http request is done and then the URL will be a string. I was using LaunchedEffect to check when the imageURL value is changed and, if it was, it would replace the painter with one that has the current image urlPiecework
@MatheusDias this would do it anyway, that's how compose works. If imageURL is different from the last time composition, image view will discard old one and start downloading new one. And null can be passed to rememberImagePainter too without problems, it'll just be empty view. Also you can check painter.state to see what's there right nowAppositive
I just checked here and it worked perfectly just as needed. I thought the rememberImagePainter would be static from the first parameters, but thank you so much!Piecework
D
5

For Coil 2.2.+ It has remeberAsyncImagePainter instead off rememberImagePainter

Image(painter = rememberAsyncImagePainter(model = imageUrl,
                imageLoader = ImageLoader.Builder(context).crossfade(true).build()),
                contentDescription = "images")
Degrading answered 16/11, 2022 at 4:1 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.