Reputation: 169
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.
I don't want this. (the code above shows this animation).
I need this with "setImageAssetDelegate" method.
Does anybody have any idea about this?
Upvotes: 1
Views: 7069
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
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