https://kotlinlang.org logo
#compose
Title
# compose
j

jean

05/30/2022, 6:10 PM
I’m still struggling with displaying images from URL inside a
LazyColumn
with
coil
Copy code
items(photos) { photo ->
    Card(
        modifier = Modifier.fillMaxWidth()
    ) {
        Column {
            Image(
                painter = rememberAsyncImagePainter(model = photo.url),
                contentDescription = "location image",
                contentScale = ContentScale.Crop,
                modifier = Modifier.fillMaxWidth()
                    .height(160.dp)
            )
            Text(
                text = photo.title,
                style = MaterialTheme.typography.h6,
                modifier = Modifier.padding(8.dp)
            )
            Text(
                text = "lat: ${photo.lat} / lon: ${photo.lon}",
                modifier = Modifier.padding(start = 8.dp, bottom = 16.dp)
            )
        }
    }
}
This is quite unstable, some picture loads and some doesn’t. Any idea what I’m doing wrong here?
f

FunkyMuse

05/30/2022, 7:01 PM
Use AsyncImage from coil? It's right there in the documentation https://coil-kt.github.io/coil/compose/
j

jean

05/30/2022, 7:05 PM
I tried with both, same result every time
l

Leland Richardson [G]

05/30/2022, 7:44 PM
if you can get reliable simple repro with the AsyncImage API, i would suggest filing a bug with the code. It could be something funky going on with lazy. However i have used AsyncImage with LazyColumn with lots of success so not sure what the error case you’re running into here is. feel free to tag me with the bug once you have a simple repro
j

jean

05/30/2022, 8:00 PM
I haven’t been able to make the problem appears consistently at all, that’s my problem. I can’t figure out what I’m doing wrong
l

Leland Richardson [G]

05/30/2022, 8:01 PM
yeah, gotcha. consistent as in “if i play around with it and fling back and forth wildly it usually happens” would be consistent enough fwiw
j

jean

05/30/2022, 8:12 PM
I don’t even need to fling, even out of 3 images, 1 might load and not the others
l

Leland Richardson [G]

05/30/2022, 8:13 PM
see anything strange in logcat?
r

Ronald Toshkollari

05/30/2022, 8:25 PM
Also just can you check if this works with other frameworks like Glide? It might be something wrong with the API
f

FunkyMuse

05/30/2022, 9:57 PM
Try if the image url actually loads from a browser it may be problem with it
j

jean

05/30/2022, 10:01 PM
I’m seeing this in Logcat, nothing wrong at first glance :
Copy code
StackLog: 
[android.net.ConnectivityManager.sendRequestForNetwork(ConnectivityManager.java:3925)] 
[android.net.ConnectivityManager.sendRequestForNetwork(ConnectivityManager.java:3967)] 
[android.net.ConnectivityManager.registerNetworkCallback(ConnectivityManager.java:4349)] 
[android.net.ConnectivityManager.registerNetworkCallback(ConnectivityManager.java:4319)] 
[coil.network.RealNetworkObserver.<init>(NetworkObserver.kt:88)] 
[coil.network.NetworkObserverKt.NetworkObserver(NetworkObserver.kt:33)] 
[coil.util.SystemCallbacks.<init>(SystemCallbacks.kt:31)] 
[coil.RealImageLoader.<init>(RealImageLoader.kt:79)] 
[coil.ImageLoader$Builder.build(ImageLoader.kt:517)] 
[coil.ImageLoaders.create(ImageLoaders.kt:16)] 
[coil.Coil.newImageLoader(Coil.kt:64)] 
[coil.Coil.imageLoader(Coil.kt:29)] 
[coil.compose.ImageLoaderProvidableCompositionLocal.getCurrent(LocalImageLoader.kt:57)] 
[coil.compose.SingletonAsyncImagePainterKt.rememberAsyncImagePainter-19ie5dc(SingletonAsyncImagePainter.kt:100)] 
[com.jeantuffier.challenge.ui.screen.record.RecordScreenKt$ListOfPictures$1$2$1.invoke(RecordScreen.kt:125)] 
[com.jeantuffier.challenge.ui.screen.record.RecordScreenKt$ListOfPictures$1$2$1.invoke(RecordScreen.kt:122)] 
[androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:107)] 
[androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34)] 
[androidx.compose.material.SurfaceKt$Surface$6.invoke(Surface.kt:268)] 
[androidx.compose.material.SurfaceKt$Surface$6.invoke(Surface.kt:255)] 
[androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:107)] 
[androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34)] 
[androidx.compose.runtime.CompositionLocalKt.CompositionLocalProvider(CompositionLocal.kt:228)] 
[androidx.compose.material.SurfaceKt.Surface-F-jzlyU(Surface.kt:252)] 
[androidx.compose.material.SurfaceKt.Surface-F-jzlyU(Surface.kt:110)] 
[androidx.compose.material.CardKt.Card-F-jzlyU(Card.kt:66)] 
[com.jeantuffier.challenge.ui.screen.record.RecordScreenKt$ListOfPictures$1$invoke$$inlined$items$default$4.invoke(LazyDsl.kt:419)] 
[com.jeantuffier.challenge.ui.screen.record.RecordScreenKt$ListOfPictures$1$invoke$$inlined$items$default$4.invoke(LazyDsl.kt:143)] 
[androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:135)] 
[androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34)] 
[androidx.compose.foundation.lazy.LazyListItemsSnapshot.Item(LazyListItemProviderImpl.kt:99)] 
[androidx.compose.foundation.lazy.LazyListItemProviderImpl.Item(LazyListItemProviderImpl.kt:126)] 
[androidx.compose.foundation.lazy.layout.LazyLayoutItemContentFactory$CachedItemContent$createContentLambda$1$1.invoke(LazyLayoutItemContentFactory.kt:119)] 
[androidx.compose.foundation.lazy.layout.LazyLayoutItemContentFactory$CachedItemContent$createContentLambda$1$1.invoke(LazyLayoutItemContentFactory.kt:118)] 
[androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:107)] 
[androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34)] 
[androidx.compose.runtime.CompositionLocalKt.CompositionLocalProvider(CompositionLocal.kt:228)] 
[androidx.compose.runtime.saveable.SaveableStateHolderImpl.SaveableStateProvider(SaveableStateHolder.kt:84)] 
[androidx.compose.foundation.lazy.layout.LazyLayoutItemContentFactory$CachedItemContent$createContentLambda$1.invoke(LazyLayoutItemContentFactory.kt:118)] 
[androidx.compose.foundation.lazy.layout.LazyLayoutItemContentFactory$CachedItemContent$createContentLambda$1.invoke(LazyLayoutItemContentFactory.kt:110)] 
[androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:107)] 
[androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34)] 
[androidx.compose.runtime.RecomposeScopeImpl.compose(RecomposeScopeImpl.kt:142)] 
[androidx.compose.runtime.ComposerImpl.recomposeToGroupEnd(Composer.kt:2351)] 
[androidx.compose.runtime.ComposerI
I will try with
com.github.skydoves:landscapist-glide
and see if there’s any difference. @FunkyMuse I did and the pictures load just fine in my browser (firefox)
After some more investigation, it seems only specific images don’t load with coil. For example, those images from Flickr : 1.

https://live.staticflickr.com/65535/52109739512_df27226ce9.jpg

does not show up. 2.

https://live.staticflickr.com/65535/52109792312_2b2e795fb3.jpg

shows up. And that consistently, I tried several times. Using
GlideImage
seems to work without any issue.
Copy code
GlideImage(
    imageModel = photo.url,
    contentDescription = "location image",
    contentScale = ContentScale.Crop,
    modifier = Modifier
        .fillMaxWidth()
        .height(160.dp)
)
l

Leland Richardson [G]

05/30/2022, 10:37 PM
Do they also not show up when you try outside of the LazyColumn?
if so, i would file a bug against coil. seems like an image loading problem and not some weird interaction with LazyColumn (which was what i thought it might be initially)
c

Colin White

05/30/2022, 10:54 PM
I just tested out those URLs locally and the server is returning a 503 for the first image; the second image works fine on my Pixel 3. The first image seems to work fine in a web browser
You can turn on Coil’s logging using a `DebugLogger`: https://coil-kt.github.io/coil/faq/#how-do-i-enable-logging to have it log errors
j

jean

05/31/2022, 8:04 AM
I noticed the 503 error too, since it works with
GlideImage
I guess it is a
coil
issue then. I’ll fill up a report
@Colin White I don’t see any
logger
function when configuring the image loader
Copy code
ImageRequest.Builder(LocalContext.current)
    .data(photo.url)
    .logger(DebugLogger()) // that doesn't exist
    .build()
Where is it supposed to be set?
c

Colin White

05/31/2022, 6:31 PM
@jean That’s an
ImageRequest
. The
ImageLoader
can be configured like this: https://coil-kt.github.io/coil/getting_started/#image-loaders
The first image now works correctly for me. Seems like it might have been a temporary server issue.
j

jean

06/01/2022, 6:21 AM
That’s an
ImageRequest
Right, I guess I need a bit more sleep hehe
133 Views