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

Bradleycorn

11/12/2020, 12:09 AM
Anyone using the
CoilImage
composable from the Accompanist library that @cb put together? I’m wondering what’s the best way to use a placeholder image resource when my composable is displayed via a
@Preview
? During preview the image state is
Empty
, so I thought about using the content composable and setting a placeholder image when image state is empty. That works. But, the placeholder image is also displayed briefly (before the actual image is loaded) when the app is run on a device, and I don’t want that.
👍 1
t

Tash

11/12/2020, 12:12 AM
is the placeholder composable configurable? i.e. in the
@Preview
you could pass in a placeholder composable, but in the real implementation it could be blank?
b

Bradleycorn

11/12/2020, 12:17 AM
Not really, the image is part of another composable that is being previewed. I have a
BlogPost(post: Post)
composable that takes a post object and renders the blog post. It contains an image, title, author, text, etc. So the CoilImage is in the BlogPost composable. I want to build a Preview for BlogPost like so:
Copy code
@Preview
@Composable
fun postPreview() {
    val post = GetMockPost()
    BlogPost(post)
}
r

Rafs

11/12/2020, 12:20 AM
CoilImage
started crashing after I upgraded to
alpha06
b

Bradleycorn

11/12/2020, 12:21 AM
I guess I could essentially do what you suggested, giving
BlogPost
a “slot api” so that you could pass it content for the “empty” state:
Copy code
@Composable
fun BlogPost(
    post: Post, 
    empty: @Composable()->Unit = {}, 
    content: @Composable () -> Unit =())
That’d work. Just seems not great to expose a slot api just so that I can do a preview.
1
t

Tash

11/12/2020, 12:25 AM
Maybe BlogPost could have just one slot for the content, be it image, text etc. Then, the Composable that renders the image can further accept an empty Composable argument. That way you'd be setting up for making BlogPost content more configurable as well.
Then in your Preview, you'd call BlogPost, pass in the Image Composable in the body, and within the Image Composable body, you'd pass in some empty placeholder.
b

Bradleycorn

11/12/2020, 12:30 AM
Wait a minute
I’m dumb
I said, “I thought about using the content composable and setting a placeholder image when image state is empty. That works. But, the placeholder image is also displayed briefly (before the actual image is loaded) when the app is run on a device,” The reason the placeholder image shows up when running the app on a device is because … I’m NOT running “the app” on a device. I have been running the PREVIEW on a device 🤦 (by clicking the little “deploy preview” icon). If I run my actual app, it doesn’t go through that initial “empty” state (or if it does, it’s so fast you don’t see it).
🙈 1
so, debugging confirmed it DOES go through the empty image state first. So, probably shouldn’t trust that it’ll always recompose fast enough that you don’t see it. So, I guess I’m back to providing an “empty” slot in my
BlogPost
composable so that I can provide an image during preview, and nothing when the app runs.
t

Tash

11/12/2020, 1:02 AM
Or, even something like:
Copy code
@Composable
fun BlogPost(post: Post, content: @Composable: () -> Unit) {
   ...
}

@Composable
fun BlogImageContent(placeholder: @Composable: () -> Unit) {
   ...
}

@Preview
fun BlogPreview() {
   BlogPost {
      BlogImageContent {
           placeholder()
       }
    }
}
c

cb

11/12/2020, 7:24 AM
The placeholder image is also displayed briefly (before the actual image is loaded) when the app is run on a device, and I don't want that.
Sounds like a bug to me. Initial thought is that I could change the logic so that the placeholder is only shown after X milliseconds after the request starts.
b

Bradleycorn

11/12/2020, 9:54 PM
@cb Shall I file an issue on the repo?
c

cb

11/12/2020, 9:54 PM
Yes please
b

Bradleycorn

11/12/2020, 9:55 PM
👍
Added some additional details