diff --git a/lib/src/composition.dart b/lib/src/composition.dart index 8274d2b7..4c38792a 100644 --- a/lib/src/composition.dart +++ b/lib/src/composition.dart @@ -191,6 +191,12 @@ class LottieComposition { return roundedProgress; } + void dispose() { + for (var image in images.values) { + image.imageProvider?.evict(); + } + } + @override String toString() { final sb = StringBuffer('LottieComposition:\n'); diff --git a/lib/src/lottie.dart b/lib/src/lottie.dart index 1b1faeb3..cb0d32a4 100644 --- a/lib/src/lottie.dart +++ b/lib/src/lottie.dart @@ -30,11 +30,13 @@ class Lottie extends StatefulWidget { this.delegates, this.options, bool? addRepaintBoundary, + bool? autoDisposeImage, this.filterQuality, }) : animate = animate ?? true, reverse = reverse ?? false, repeat = repeat ?? true, - addRepaintBoundary = addRepaintBoundary ?? true; + addRepaintBoundary = addRepaintBoundary ?? true, + autoDisposeImage = autoDisposeImage ?? true; /// Creates a widget that displays an [LottieComposition] obtained from an [AssetBundle]. static LottieBuilder asset( @@ -58,6 +60,7 @@ class Lottie extends StatefulWidget { AlignmentGeometry? alignment, String? package, bool? addRepaintBoundary, + bool? autoDisposeImage, FilterQuality? filterQuality, WarningCallback? onWarning, }) => @@ -82,6 +85,7 @@ class Lottie extends StatefulWidget { alignment: alignment, package: package, addRepaintBoundary: addRepaintBoundary, + autoDisposeImage: autoDisposeImage, filterQuality: filterQuality, onWarning: onWarning, ); @@ -106,6 +110,7 @@ class Lottie extends StatefulWidget { BoxFit? fit, AlignmentGeometry? alignment, bool? addRepaintBoundary, + bool? autoDisposeImage, FilterQuality? filterQuality, WarningCallback? onWarning, }) => @@ -128,6 +133,7 @@ class Lottie extends StatefulWidget { fit: fit, alignment: alignment, addRepaintBoundary: addRepaintBoundary, + autoDisposeImage: autoDisposeImage, filterQuality: filterQuality, onWarning: onWarning, ); @@ -152,6 +158,7 @@ class Lottie extends StatefulWidget { BoxFit? fit, AlignmentGeometry? alignment, bool? addRepaintBoundary, + bool? autoDisposeImage, FilterQuality? filterQuality, WarningCallback? onWarning, }) => @@ -174,6 +181,7 @@ class Lottie extends StatefulWidget { fit: fit, alignment: alignment, addRepaintBoundary: addRepaintBoundary, + autoDisposeImage: autoDisposeImage, filterQuality: filterQuality, onWarning: onWarning, ); @@ -198,6 +206,7 @@ class Lottie extends StatefulWidget { BoxFit? fit, AlignmentGeometry? alignment, bool? addRepaintBoundary, + bool? autoDisposeImage, FilterQuality? filterQuality, WarningCallback? onWarning, }) => @@ -220,6 +229,7 @@ class Lottie extends StatefulWidget { fit: fit, alignment: alignment, addRepaintBoundary: addRepaintBoundary, + autoDisposeImage: autoDisposeImage, filterQuality: filterQuality, onWarning: onWarning, ); @@ -312,6 +322,10 @@ class Lottie extends StatefulWidget { /// This property is `true` by default. final bool addRepaintBoundary; + /// Indicate to automatically evict image from cache when object dispose + /// This property is `true` by default. + final bool autoDisposeImage; + /// The quality of the image layer. See [FilterQuality] /// [FilterQuality.high] is highest quality but slowest. /// @@ -364,6 +378,9 @@ class _LottieState extends State with TickerProviderStateMixin { @override void dispose() { _autoAnimation.dispose(); + if (widget.autoDisposeImage && widget.composition != null) { + widget.composition!.dispose(); + } super.dispose(); } diff --git a/lib/src/lottie_builder.dart b/lib/src/lottie_builder.dart index d2112398..6d45de1b 100644 --- a/lib/src/lottie_builder.dart +++ b/lib/src/lottie_builder.dart @@ -58,6 +58,7 @@ class LottieBuilder extends StatefulWidget { this.fit, this.alignment, this.addRepaintBoundary, + this.autoDisposeImage, this.filterQuality, this.onWarning, }); @@ -83,6 +84,7 @@ class LottieBuilder extends StatefulWidget { this.fit, this.alignment, this.addRepaintBoundary, + this.autoDisposeImage, this.filterQuality, this.onWarning, }) : lottie = NetworkLottie(src, @@ -117,6 +119,7 @@ class LottieBuilder extends StatefulWidget { this.fit, this.alignment, this.addRepaintBoundary, + this.autoDisposeImage, this.filterQuality, this.onWarning, }) : lottie = FileLottie(file, imageProviderFactory: imageProviderFactory); @@ -143,6 +146,7 @@ class LottieBuilder extends StatefulWidget { this.alignment, String? package, this.addRepaintBoundary, + this.autoDisposeImage, this.filterQuality, this.onWarning, }) : lottie = AssetLottie(name, @@ -170,6 +174,7 @@ class LottieBuilder extends StatefulWidget { this.fit, this.alignment, this.addRepaintBoundary, + this.autoDisposeImage, this.filterQuality, this.onWarning, }) : lottie = MemoryLottie(bytes, imageProviderFactory: imageProviderFactory); @@ -361,6 +366,10 @@ class LottieBuilder extends StatefulWidget { /// This property is `true` by default. final bool? addRepaintBoundary; + /// Indicate to automatically evict image from cache when object dispose + /// This property is `true` by default. + final bool? autoDisposeImage; + /// The quality of the image layer. See [FilterQuality] /// [FilterQuality.high] is highest quality but slowest. /// @@ -439,6 +448,14 @@ class _LottieBuilderState extends State { } } + @override + void dispose() { + if (widget.autoDisposeImage != null && widget.autoDisposeImage!) { + sharedLottieCache.evict(widget.lottie); + } + super.dispose(); + } + void _load() { var provider = widget.lottie; _loadingFuture = widget.lottie.load().then((composition) { @@ -495,6 +512,7 @@ class _LottieBuilderState extends State { fit: widget.fit, alignment: widget.alignment, addRepaintBoundary: widget.addRepaintBoundary, + autoDisposeImage: widget.autoDisposeImage, filterQuality: widget.filterQuality, ); diff --git a/lib/src/lottie_image_asset.dart b/lib/src/lottie_image_asset.dart index c2099696..c862f586 100644 --- a/lib/src/lottie_image_asset.dart +++ b/lib/src/lottie_image_asset.dart @@ -1,5 +1,7 @@ import 'dart:ui' as ui; +import 'package:flutter/widgets.dart'; + class LottieImageAsset { final int width; final int height; @@ -7,13 +9,15 @@ class LottieImageAsset { final String fileName; final String dirName; ui.Image? loadedImage; + ImageProvider? imageProvider; LottieImageAsset( {required this.width, required this.height, required this.id, required this.fileName, - required this.dirName}); + required this.dirName, + this.imageProvider}); @override String toString() => diff --git a/lib/src/providers/load_image.dart b/lib/src/providers/load_image.dart index 27d6f115..f09c7604 100644 --- a/lib/src/providers/load_image.dart +++ b/lib/src/providers/load_image.dart @@ -8,6 +8,8 @@ typedef LottieImageProviderFactory = ImageProvider? Function(LottieImageAsset); Future loadImage(LottieComposition composition, LottieImageAsset lottieImage, ImageProvider provider) { + lottieImage.imageProvider = provider; + var completer = Completer(); var imageStream = provider.resolve(ImageConfiguration.empty); late ImageStreamListener listener;