Dynamically replace Image in Lottie animation at runtime
Asked Answered
L

4

9

I have an After Effects animation, super simple, of a square moving around (AE shape). I export the animation as a .json using Bodymovin, and add the json file using Lottie in my project. So far, so good.

The problem starts here --> during runtime, replace that "square" with an image I have in my project as well. Because this image may change, I can't add it statically to my AE animation, so need to dynamically add it during runtime. There's almost no information on how to do this in Android?

Levin answered 4/2, 2019 at 11:31 Comment(1)
Could you provide the json file related? I am trying to build something similar but it looks like the lottie json file is not exported correctly.Guesswarp
L
5

Managed to do this: the problem was that my After Effects animation had a vector shape, and I was trying to replace this. After I changed the original animation to have a .png instead, I could replace the Image at runtime. Worked just fine.

// First I converted the png I wanted to see at runtime to a bitmap:

Bitmap bitmapImage = BitmapFactory.decodeResource(getResources(), R.drawable.imageBlah);

// I used the lambda: 

lottieAnimationView.setImageAssetDelegate( lottieImageAsset -> bitmapImage);

This worked for ONE image, now I'm going to see how about replacing multiple images at runtime.

Levin answered 6/2, 2019 at 11:23 Comment(2)
Did you find any solution for replacing multiple images at runtime?Incompliant
Could you provide the json file related? I am trying to build something similar but it looks like the lottie json file is not exported correctly.Guesswarp
P
13

LottieAnimationView extends an ImageView. In other words, the LottieAnimationView is also an ImageView.

So, you can set a image on LottieAnimationView the same way you set a image to a ImageView

For example:

if (isAnimated) {
    mLottieView.setAnimation("<json file name from asset folder>");
} else {
    mLottieView.setImageResource(R.drawable.square_image);
}

This is just an example about how you can use the same view to play an animation (json file) or image like any ImageView..

Patsis answered 5/2, 2019 at 16:25 Comment(0)
G
5

Lottie has one XML attribute app:lottie_imageAssetsFolder, which can also be set at run-time: animationView.setImageAssetsFolder("images/");. with that set, one can reference images in the json. this is documented in-line; see the comments above line #599 and #630. this is also explained in the documentation (src/assets might not be an option, since it is not writable):

Sometimes, you don't have the images bundled with the device. You may do this to save space in your apk or if you downloaded the animation from the network. To handle this case, you can set an ImageAssetDelegate on your LottieAnimationView or LottieDrawable. The delegate will be called every time Lottie tries to render an image. It will pass the image name and ask you to return the bitmap. If you don't have it yet (if it's still downloading, for example) then just return null and Lottie will continue to ask on every frame until you return a non-null value.

animationView.setImageAssetDelegate(new ImageAssetDelegate() {
    @Override
    public Bitmap fetchBitmap(LottieImageAsset asset) {
        if (downloadedBitmap == null) {
            // We don't have it yet. Lottie will keep asking until we return a non-null bitmap.
           return null;
        }
        return downloadedBitmap;
    }
});
Gilda answered 4/2, 2019 at 11:53 Comment(2)
Thanks Martin! I need to ask though, what would 'downloadedBitmap' be here? thanksLevin
Would the 'dowloadedBitmap' be a bitmap I need to create (the external image I want to lead at runtime, converted to bitmap?), or how does this would work? Thanks!Levin
L
5

Managed to do this: the problem was that my After Effects animation had a vector shape, and I was trying to replace this. After I changed the original animation to have a .png instead, I could replace the Image at runtime. Worked just fine.

// First I converted the png I wanted to see at runtime to a bitmap:

Bitmap bitmapImage = BitmapFactory.decodeResource(getResources(), R.drawable.imageBlah);

// I used the lambda: 

lottieAnimationView.setImageAssetDelegate( lottieImageAsset -> bitmapImage);

This worked for ONE image, now I'm going to see how about replacing multiple images at runtime.

Levin answered 6/2, 2019 at 11:23 Comment(2)
Did you find any solution for replacing multiple images at runtime?Incompliant
Could you provide the json file related? I am trying to build something similar but it looks like the lottie json file is not exported correctly.Guesswarp
D
3

This is how you can load images into lottie dynamically. In this example, I am loading via URL. You can load a bundled image as well similarly.

Glide.with(this)
            .asBitmap()
            .load(url)
            .into(object : CustomTarget<Bitmap>(){
                override fun onResourceReady(resource: Bitmap, transition: Transition<in Bitmap>?) {
                    lottie.addLottieOnCompositionLoadedListener {
                        val scaledBitmap = Bitmap.createScaledBitmap(resource, 282, 167, false)
                        lottie.updateBitmap("image_0", scaledBitmap)
                    }
                }
                override fun onLoadCleared(placeholder: Drawable?) {
                }
            })

image_0 is the id of the image you want to replace in lottie json under "assets" object.

scaling the bitmap is optional.

"assets": [{
    "id": "image_0",
    "w": 282,
    "h": 167,
    "u": ""}]
Disposition answered 10/11, 2021 at 15:53 Comment(2)
Could you provide the json file related? I am trying to build something similar but it looks like the lottie json file is not exported correctly.Guesswarp
if the loaded bitmap does not appear, you may prefer to use lottie.setImageBitmap(scaledBitmap)Stovall

© 2022 - 2024 — McMap. All rights reserved.