Hi, I am wondering if anyone has worked on such a ...
# compose
c
Hi, I am wondering if anyone has worked on such a problem. I have some code like this:
Copy code
@Composable
fun WeightedBox() {
  Row {
    Box(modifier = Modifier.weight(0.3f)) {
      // Hypothetical @Composable Image
      Image(...)
    }
  }
}
Basically I am trying to load an image in a Box that will be weighted to 30% width of the display. The API I’m calling to fetch the image allows me to filter the url to only fetch the size of image I need. For example, if I’m fetching
/images/pic1.jpg
but I only need it at max 400px width/height, I could fetch
/images/pic1_400x400.jpg
. Is there any way for me to know the calculated width in pixels, so that I can pass this information along with my request? Fwiw I don’t need to use Box exactly. If there’s another composable that would provide this behaviour, I can use that. I guess my use case is similar to, say, if I were making a grid of images. Thanks for any help!
s
onSizeChanged modifier will get you that information, and you can use it on an image directly Also you might want to take a look at accompanist-coil, which does exactly what you’re trying to achieve
c
I’m using accompanist-coil, I didn’t know that! I’ll check it out
thanks for responding
s
+1 for using accomplist-coil for this, there were some potential perf issues that @cb worked through in there
t
@Chris Fillmore You can use BoxWithConstraints to get the size.
Copy code
constraints.maxWidth/maxHeight
It is the size in pixel. You can also get the size in dp
c
@Chris Fillmore I had to do this once! It seems to work just fine, but I think @cb can tell me if my impl is terrible
Copy code
@Composable
fun ImageFromUrl(imageUrl: String, modifier: Modifier = Modifier) {
    CoilImage(
        data = "",
        contentDescription = null,
        fadeIn = true,
        modifier = modifier,
        requestBuilder = { size: IntSize ->
            val builder = MyUrlBuilder(width = size.width.toString(), height = size.width.toString())
            data(builder.toUrl())
        }
    )
}
c
Thanks everyone for replying! I’m grateful for the help.
c
You implementation looks fine, as long as you’re passing in some constrained bounds. You might want to look at a Coil interceptor, rather than manually hacking the request. @nickbutcher uses it in the Owl sample: https://github.com/android/compose-samples/blob/1e04af6d03ec07b0fa993b1e114cafbb78af3c93/Owl/app/src/main/java/com/example/owl/ui/utils/NetworkImage.kt
c
@cb "You implementation looks fine, as long as you’re passing in some constrained bounds." what do you mean by constrained bounds? I will look into the interceptor. Thanks
c
what do you mean by constrained bounds?
I mean that the bounds are constrained, i.e the parent has a maximum width, or you’ve set a explicit width/height. If the layout is set to wrap the content, you may get a size of
0,0
.
c
Gotcha. Yeah, basically the composable we have going on forces you to set an aspect ratio for your image, so it'll always basically meet the bounds width wise, and then set height dependent on aspect ratio set, then it'll go out to an image resize service and pull just the right image.
@cb having an issue now that CoilImage is deprecated. I re-read what you said and noticed you said I'm "manually hacking the request". Isn't that what requestBuilder should be used for?
c
Yeah, I meant hacking the URL.
requestBuilder
is mostly meant for tweaking things like the placeholder, size, etc, rather than the URL. It probably does work for that, but it's not the intention, and not tested for that
c
@cb aha. okay. So we moved from the deprecated coilImage to the new impl, and our implementation stopped working 😭 BUT I will steal the interceptor nick butcher wrote and 🤞 it works with all of the latest lib versions 😄
@cb alright after ripping my hair out a bit I found out that I was missing
contentScale: ContentScale = ContentScale.Crop,
I don't understand why I need that if I have an aspectRatio of 16:9. I'm just going to accept it that I need ContentScale.Crop, but that doesn't make sense to me. If I don't do that then my imagesize was 1080 x 1080, but if I add the ContentScale.Crop it works as expected and I get a size of 1080 x 600.
c
Paste in the function call? What’s the parent size, etc.
🙈 I think this was my fault: https://github.com/google/accompanist/pull/391
c
Ah. No worries. I tried to come up with a small sample repro quickly but I was getting some studio build issues so I put it on the back burner. Might circle back to this. Thank you!