Are deferred resources supposed to reload in the p...
# compose
a
Are deferred resources supposed to reload in the preview? I’m testing a basic drawable resource load: • Stack overflow indicates several implementations, and most of them seem to have changed (no DrawImage) • The easiest implementation
imageResource
is “likely to be removed” due to synchronous loading, and results in an AIOOB exception • The deferred loading pattern seems preferred, but does not seem to redraw once the icon loads. What is the correct approach here for loading resource content? Edit: I now realize there is a difference between
imageResource
and
vectorResource
, but the latter is also a transient API
a
Did you check
loadImageResource
?
a
loadImageResource is what I meant by the last point. I haven't tested anything on device yet but it doesn't load properly in the preview as it is deferred
a
AFAIR it worked fine. Maybe paste your code snippet here so that we could take a look?
l
I can only get the pending state resource to show by something like:
Copy code
@Preview
@Composable
fun ProfilePreview() {
        Image(loadVectorResource(id = R.drawable.ic_baseline_tag_faces_24, pendingResource = vectorResource(
        id = R.drawable.pending_24)).resource.resource!!)
}
It doesn't look like the state of the DeferredResource changes in a preview
a
You're loading the resource asynchronously with the same resource loaded synchronously as a fallback. For that case vectorResource alone seems better
l
I know, it was just an example. I edited it to be more clear. only R.drawable.pending_24 would show. The preview does not update to show the loaded value
But what would be the correct way to display a DeferredResource in an Image? I cannot find any examples either way?
a
What I had in my code is the same as yours, but without a pending resource and a box around the image. I would only load the image if the resource is not null, so the box is meant to reserve the space. As you mentioned, the preview does not show it, and I’ve looked at the tutorial again and it’s loading things synchronously. My initial problem was solved by using
vectorResource
instead of
imageResource
(not sure why there needs to be a difference API wise), so I will likely keep using that now for testing. It seems like a lot of additional work for deferred loading on what is a very common UI component
a
@Nader Jawad
n
Compose does not support the existing Android drawable APIs and we are identifying/supporting various drawable goals on a case by case basis. We intend to standardize this so that loading assets can be done irrespective of the underlying type like it works on Android today. Vector assets in compose use a completely different implementation behind the scenes and do not leverage VectorDrawable at all, similarly with underlying Bitmaps, we resolve them into ImagePainter objects instead. Take a look at VectorGraphicsDemo that shows how we load async images. This logic will most likely change in the future but it is how are approach async loading right now.
Copy code
val vectorAsset = loadVectorResource(R.drawable.ic_crane)
        vectorAsset.resource.resource?.let {
            Image(
                asset = it,
                modifier = Modifier.preferredSize(200.dp, 200.dp),
                contentScale = ContentScale.Inside
            )
        }
Originally we did not have coroutine support in compose but that was recently added so the resource loading implementation will most likely be updated to leverage coroutines. For the sake of previews, leveraging a synchronous asset load seems reasonable to confirm the visuals of the code result.
a
I have not run a project on an actual device yet, but at least in the preview, using the deferred loading does not seem to refresh (as the method docs suggest) and show the icon. I imagine many other components will employ the same kind of pattern, so would that be a TODO in the previewer or a compromise we’d have to make? Additionally, my intuition when I first saw the code is that the space held by the icon would not be reserved if the resource is pending. Wouldn’t we then be required to box that section? That would then make resource loading go from a one liner to multiple lines + a wrapping composable.
t
On a device or an emulator deferred loading is working fine. (I assume you want s.th. like showing a placeholder and than downloading an image and when it is finished showing the downloaded image.