简体   繁体   English

在运行时动态替换 Lottie 动画中的 Image

[英]Dynamically replace Image in Lottie animation at runtime

I have an After Effects animation, super simple, of a square moving around (AE shape).我有一个 After Effects 动画,超级简单,一个正方形四处移动(AE 形状)。 I export the animation as a .json using Bodymovin, and add the json file using Lottie in my project.我使用 Bodymovin 将动画导出为 .json,并在我的项目中使用 Lottie 添加 json 文件。 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.因为这个图片可能会发生变化,我无法静态添加到我的AE动画中,所以需要在运行时动态添加。 There's almost no information on how to do this in Android?几乎没有关于如何在 Android 中执行此操作的信息?

LottieAnimationView extends an ImageView . LottieAnimationView扩展了一个ImageView In other words, the LottieAnimationView is also an ImageView .换句话说, LottieAnimationView也是一个ImageView

So, you can set a image on LottieAnimationView the same way you set a image to a ImageView因此,您可以像将图像设置为ImageView一样在LottieAnimationView上设置图像

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 ..这只是关于如何使用相同的视图播放动画(json 文件)或图像的示例,就像任何ImageView ..

Lottie has one XML attribute app:lottie_imageAssetsFolder , which can also be set at run-time: animationView.setImageAssetsFolder("images/"); Lottie 有一个XML属性app:lottie_imageAssetsFolder ,也可以在运行时设置: animationView.setImageAssetsFolder("images/"); . . with that set, one can reference images in the json .使用该集合,您可以在json引用图像。 this is documented in-line;这是在线记录的; see the comments above line # 599 and # 630 .请参阅第 # 599和 # 630行上方的注释。 this is also explained in the documentation ( src/assets might not be an option, since it is not writable):这也在文档中进行了解释( src/assets可能不是一个选项,因为它不可写):

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.您可以这样做以节省 apk 中的空间,或者如果您从网络下载动画。 To handle this case, you can set an ImageAssetDelegate on your LottieAnimationView or LottieDrawable .要处理这种情况,您可以在LottieAnimationViewLottieDrawable上设置ImageAssetDelegate The delegate will be called every time Lottie tries to render an image.每次 Lottie 尝试渲染图像时都会调用该委托。 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.如果您还没有它(例如,如果它仍在下载),则只需返回 null,Lottie 将继续询问每一帧,直到您返回非空值。

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;
    }
});

Managed to do this: the problem was that my After Effects animation had a vector shape, and I was trying to replace this.设法做到这一点:问题是我的 After Effects 动画有一个矢量形状,我试图替换它。 After I changed the original animation to have a .png instead, I could replace the Image at runtime.在我将原始动画更改为 .png 后,我可以在运行时替换图像。 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.这适用于一个图像,现在我将看看如何在运行时替换多个图像。

This is how you can load images into lottie dynamically.这就是您如何将图像动态加载到 lottie 中的方法。 In this example, I am loading via URL.在这个例子中,我通过 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. image_0 是您要在“资产”对象下的 lottie json 中替换的图像的 ID。

scaling the bitmap is optional.缩放位图是可选的。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM