15

I am trying to show an image with fill width and auto height using Jetpack Compose Coil. I want the image to take the full width and auto height. But the image only showing when I specify a fixed height.

Image(
    painter = rememberImagePainter(
        data = post.image
    ),
    contentDescription = null,
    contentScale = ContentScale.Crop,
    modifier = Modifier.fillMaxWidth()
)

I tried with .fillMaxHeight() and .fillMaxSize() but it's not working. Is there any way I could achieve this?

Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
Jeeva
  • 3,975
  • 3
  • 23
  • 47

4 Answers4

17

This happens when one of view width/height is calculated as zero, which means it shouldn't be displayed and no need to download it. Check out more about the reasons in this issue on compose tracker.

You should make your size not being equal to zero. Depending you your layout it can be done with variations of width/height/aspect ratio modifiers.

If you'd like to get your image in original size, you can to add size(OriginalSize) to painter builder. This will force image to start loading. This parameter makes your view download and put into the memory full size of the image, without optimizing it for the current view. So use it carefully, only if you're sure the image won't be too big and you really can't add use size modifiers.

Image(
    painter = rememberImagePainter(
        data = post.image,
        builder = {
            size(OriginalSize)
        },
    ),
    contentDescription = null,
    contentScale = ContentScale.Crop,
    modifier = Modifier.fillMaxWidth()
)
Phil Dukhov
  • 67,741
  • 15
  • 184
  • 220
  • Thanks a lot. This one is the solution, finally. – Hasim D Nov 19 '21 at 12:22
  • Specifying min height/width for image also will force image loading. And seems like it doesn't impact image optimization. For example: Modifier.fillMaxWidth().defaultMinSize(minHeight = 1.dp) – Mike May 13 '22 at 10:41
4

With latest Coil 2.1.0 you can do like this:

val model = ImageRequest.Builder(LocalContext.current)
            .data(imageUrl)
            .size(Size.ORIGINAL)
            .crossfade(true)
            .build()
val painter = rememberAsyncImagePainter(model)
Image(
     modifier = Modifier.fillMaxWidth(),
     painter = painter,
     contentDescription = null,
     contentScale = ContentScale.FillWidth
    )
Rafael
  • 6,091
  • 5
  • 54
  • 79
1

If your image OriginalSize is to small for your composable you can also use scale(Scale.FIT) in your builder.

Your image will max fit your composable while keeping it's aspect ratio.

Image(
    rememberImagePainter(
        data = user?.photoUrl?:"",
        builder = {
            size(OriginalSize)
            scale(Scale.FIT)
            transformations(CircleCropTransformation())
        }
    ),
    contentDescription = "Picture",
    contentScale = ContentScale.FillWidth
)
elfefe
  • 68
  • 6
1

Instead of using size(OriginalSize) that impacts image optimization, you can set min height/width for image (for example 1.dp). This will force image to start loading:

Image(
    painter = rememberImagePainter(url),
    contentDescription = null,
    modifier = Modifier
        .fillMaxWidth()
        .defaultMinSize(minHeight = 1.dp),
)
Mike
  • 321
  • 4
  • 10