eyeballs
eyeballs

Reputation: 169

How to provide multiple images with Lottie on Android

I'm developing an app with Lottie animations. One of lottie animation needs two image files(img_0.png, img1_.png).

For example,

lottie json file [ data.json ] : {"v":"5.1.7","fr":60,"ip":0,"op":120,"w":180,"h":200,"nm":"2","ddd":0,"assets":[{"id":"image_0","w":96,"h":96,"u":"images/","p":"img_0.png"},{"id":"image_1","w":180,"h":180,"u":"images/","p":"img_1.png"}],....

I can't prepare all images for LottieAnimationView in main/assets folder, so I'm using "setImageAssetDelegate" method to get multiple images from URLs asynchronously.

This is my code:

        Glide.with(this)
            .asBitmap()
            .load("https://www.google.co.kr/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png")
            .into(new SimpleTarget<Bitmap>() {
                @Override
                public void onResourceReady(final Bitmap resource, Transition<? super Bitmap> transition) {

                    LottieAnimationView lottie = findViewById(R.id.lottie);
                    lottie.setImageAssetDelegate(new ImageAssetDelegate() {
                        @Override
                        public Bitmap fetchBitmap(LottieImageAsset asset) {
                            return resource;
                        }
                    });
                    lottie.playAnimation();
                }
            });

But if I use "setImageAssetDelegate" method, I can put only one image to Lottie. I want to put multiple different images in one Lottie animation.

not like this

I don't want this. (the code above shows this animation).

but like this

I need this with "setImageAssetDelegate" method.

Does anybody have any idea about this?

Upvotes: 1

Views: 7069

Answers (2)

Harminder Singh
Harminder Singh

Reputation: 1766

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. You can repeat this process similarly for image_1 as well.

"assets": [{
    "id": "image_0",
    "w": 282,
    "h": 167,
    "u": ""}]

Scaling the bitmap is optional.

Upvotes: 1

fweigl
fweigl

Reputation: 22038

Fetching the images asynchronously will not work. The ImageAssetDelegate is meant to be a "provider" of the images that the animation needs when playing.

Its' method public Bitmap fetchBitmap(LottieImageAsset asset) will be called for each image in the animation while the animation is playing and it's your responsibility to provide the correct one, where the LottieImageAsset passed to that method will give you the details on which image is needed at that moment taken from the animation json file.

You can use Glide to fetch these images, need to keep in mind though that you'll have to fetch them synchonously and the animation will not continue playing until that image is loaded / provided by you.

An example:

LottieAnimationView lottie = findViewById(R.id.lottie);
lottie.setImageAssetDelegate(new ImageAssetDelegate() {
    @Override
    public Bitmap fetchBitmap(LottieImageAsset asset) {
        return Glide.loadSychronous("http://" + asset.getId + ".png");
    }
});
lottie.playAnimation(); 

Note: this is pseudo-code, you'll have to look up how to load images synchronously with Glide and you'll have to come up with a way to match the image id with the correct image url.

Another route would be using Glide to load all the images needed for the animation, save them (in memory or external storage) and only then start playing the animation; This might work for a small animation; for anything larger you'll run into trouble because a. the loading of all images takes too long or b. you run out of memory.

Upvotes: 2

Related Questions