You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter中如何更新Lottie JSON文件的资源图片值?

解决Flutter中Lottie动画图片替换失效问题

问题描述

我在项目中使用Lottie JSON文件,已成功渲染Lottie动画。需要更新JSON文件中的资源图片,替换动画内的图标,但尝试的代码未生效——动画先显示默认值,随后变为空白。

原Lottie文件

{
  "v": "4.8.0",
  "meta": {
    "g": "LottieFiles AE 3.1.1",
    "a": "",
    "k": "",
    "d": "",
    "tc": ""
  },
  "fr": 30,
  "ip": 0,
  "op": 300,
  "w": 400,
  "h": 400,
  "nm": "Comp 2",
  "ddd": 1,
  "assets": [
    {
      "id": "image_0",
      "w": 32,
      "h": 32,
      "u": "",
      "p": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAACXBIWXMAAAABAAAAAQBPJcTWAAAAJHpUWHRDcmVhdG9yAAAImXNMyU9KVXBMK0ktUnBNS0tNLikGAEF6Bs5qehXFAAADdUlEQVRYhc2XzWsbRxjGfzO7lTCx15ccShVBfUvIQerF1L44l8TQkw1tc6xS7JOJiZN723/AaXDoqaEVPRlhsE+FHgIWBpvqUuvg6NiCvKFQXSS1CK13d3rY9Uqrr518QZ7T7ny87/POO/O8MwJN/PtDJm/4agXELVBLo0eJMqhDT4qD6Q37VMeuSBrQ2ckUlFAPBOR0yQIoqAolnkxt2sXXItD5/sOPMY3i+Gh1Icq4XmFq6++/tAn89/SjFQlFYPbNnEdo+lC4cv/lwWCHHGzo7GQKEvbfonOAWQn7nZ1MYbAjtgJh5Pu6Vs3cOqpdx7ePUd2W1hwfVvtXIiIQ5Fyeohm5SFuk12sAdH/5FDO3BoBXK+E3ziZNbeL6+cs90UuBaRQnORdpC3P+ETKzAIDMLAKg2ueoVh3jxl2M3BqkrSTus6GvwC0EeU/a7TKziDn/EHgIThvVbQYEWvWAVGoGAN8+SSIAqKXOTqYwtWkXJYAS6oHGLFTjRfCRmkHMXAuJLZBa3Yv6hZXVMRX5FKHC/aE1C0it7kVpGAev+gy3sp24MT0pPpGBvOpDtc97P04bZ/cO7tF3sXYjt8YHn/2UaMvw1YoMtF0f/dH79jF+4wy3+iPO7u1eisJx8urNBGvilnwVqRVWNso9gH/e23Cq28K3j+MTEk+EWjJ1nQNDuZfXFjCcJqpVR1hZjBt34+Yn6wEQHkN9Aovx/7ll5NzyyLFu5bGWOg7VgskEeiugGi/wqs9ieb+E/+dvuJVtPZu6zgfz79VKXBx9S3f3Ns7+5/ENOLeMOf/o7RAQVjbI7/UvY+39G863T3B+/TpuOEErLmGG16ixJyG1uheLHACnPVRwhsZoQZRNUIfASALy6s3RhlMzpL/6HdU4w//nDJG2hk9Av2CNhTpMlGJhZQNRySxiXP9Cw2gAZ/dOUlkOpHh6wz5VUB3LsVXHq5Vwj76J2tzK4/EROm0unm8lOldQnd6wT00AocQThPp50oT++u9WtjHz6wBcPN9CterROL1yHPokFKKpTbvYeZpwJwhl1bdPAo0P679XK2k5HHBfvryu95TQ9QqTrmRerYRXK0X1XjfSEWjieoWISn/Pq15KXweDl9KYEF25//IAJe69M+9K3Bt8G7x/DxMIV8L184FKvilEGdfPj3IO7/PjdBDv6nn+P/q8gqi9Sz0EAAAAAElFTkSuQmCC",
      "e": 1
    }
  ],
  "layers": [
    {
      "ddd": 1,
      "ind": 1,
      "ty": 2,
      "nm": "Layer 1",
      "refId": "image_0",
      "sr": 1,
      "ks": {
        "o": {
          "a": 0,
          "k": 100,
          "ix": 11
        },
        "rx": {
          "a": 0,
          "k": 0,
          "ix": 8
        },
        "ry": {
          "a": 0,
          "k": 0,
          "ix": 9
        },
        "rz": {
          "a": 0,
          "k": 0,
          "ix": 10
        },
        "or": {
          "a": 0,
          "k": [
            0,
            0,
            0
          ],
          "ix": 7
        },
        "p": {
          "a": 1,
          "k": [
            {
              "i": {
                "x": 0.833,
                "y": 0.833
              },
              "o": {
                "x": 0.167,
                "y": 0.167
              },
              "t": 0,
              "s": [
                65,
                217,
                0
              ],
              "to": [
                41.667,
                0,
                0
              ],
              "ti": [
                -41.667,
                0,
                0
              ]
            },
            {
              "t": 96,
              "s": [
                315,
                217,
                0
              ]
            }
          ],
          "ix": 2
        },
        "a": {
          "a": 0,
          "k": [
            16,
            16,
            0
          ],
          "ix": 1
        },
        "s": {
          "a": 0,
          "k": [
            100,
            100,
            100
          ],
          "ix": 6
        }
      },
      "ao": 0,
      "ip": 0,
      "op": 300,
      "st": 0,
      "bm": 0
    }
  ],
  "markers": []
}

原尝试代码

class LottieSample extends StatelessWidget {
  LottieSample({Key? key}) : super(key: key);

  LottieImageAsset updatedAsset = LottieImageAsset(
      width: 32,
      height: 32,
      id: 'image_0',
      fileName:
          'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAANsAAADmCAMAAABruQABAAAAhFBMVEUAAAD39/f////7+/vb29v19fX29vbk5OTIyMjg',
      dirName: '');

  @override
  Widget build(BuildContext context) {
    var asset2 = Lottie.asset(
        'assets/lottie/revolve.json',
        delegates: LottieDelegates(
          image: (LottieComposition composition, LottieImageAsset asset) {
            if (asset.id == 'image_0') {
              asset = updatedAsset;
            }
            if (composition.images.containsKey('image_0')) {
              print(composition.images['image_0']?.dirName);
              print(composition.images['image_0']?.loadedImage);
              print(composition.images['image_0']?.fileName);
              composition.images.update(
                'image_0',
                (value) => updatedAsset);
            }
          },
        ),
      );
    return Container(
      color: Colors.white,
      child: asset2,
    );
  }
}

问题原因

  1. LottieDelegates的image回调使用错误:该回调需要返回替换后的资源,而非直接修改传入的asset变量或composition.images集合——LottieComposition是不可变对象,直接修改不会触发资源更新。
  2. base64字符串不完整:你提供的替换图片base64内容截断,导致图片加载失败,最终显示空白。

正确实现方式

方式1:使用完整的Base64字符串替换

class LottieSample extends StatelessWidget {
  LottieSample({Key? key}) : super(key: key);

  // 注意:这里需要传入完整有效的base64字符串
  final String newImageBase64 = 'data:image/png;base64,完整的base64内容...';

  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.white,
      child: Lottie.asset(
        'assets/lottie/revolve.json',
        delegates: LottieDelegates(
          image: (composition, asset) {
            // 匹配到目标图片ID时,返回新的LottieImageAsset
            if (asset.id == 'image_0') {
              return LottieImageAsset(
                id: asset.id,
                width: asset.width,
                height: asset.height,
                fileName: newImageBase64,
                dirName: '',
              );
            }
            // 其他资源保持原样
            return asset;
          },
        ),
      ),
    );
  }
}

方式2:使用本地资源图片替换

如果图片放在项目assets目录下(需在pubspec.yaml中声明),可以直接使用资源路径:

class LottieSample extends StatelessWidget {
  LottieSample({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.white,
      child: Lottie.asset(
        'assets/lottie/revolve.json',
        delegates: LottieDelegates(
          image: (composition, asset) {
            if (asset.id == 'image_0') {
              return LottieImageAsset(
                id: asset.id,
                width: asset.width,
                height: asset.height,
                fileName: 'assets/icons/new_icon.png',
                dirName: '',
              );
            }
            return asset;
          },
        ),
      ),
    );
  }
}

关键说明

  • 确保替换的图片尺寸与原Lottie中定义的width/height一致,避免拉伸变形
  • Base64字符串必须完整,可通过在线工具将图片转换为完整的Data URL格式
  • 不需要修改composition对象,Lottie框架会自动使用回调返回的资源进行渲染

内容的提问来源于stack exchange,提问作者Android

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 08:25:23