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, ); } }
问题原因
- LottieDelegates的image回调使用错误:该回调需要返回替换后的资源,而非直接修改传入的
asset变量或composition.images集合——LottieComposition是不可变对象,直接修改不会触发资源更新。 - 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
相关产品推荐
相关产品推荐

