Compare commits

..

5 Commits

Author SHA1 Message Date
9584834956 Prepare version 1.0.0 (#136) 2021-02-24 20:14:13 +01:00
d0edd1b3ee Fix web version (#135) 2021-02-22 08:42:09 +01:00
6831f475d4 Add an image delegate to dynamically change images (#130)
And allow to use an imageProviderFactory with a zip file.
2021-02-08 22:25:58 +01:00
bbfe04f00d Remove prints (#129) 2021-02-06 14:42:46 +01:00
5b7fde198a Fix bounds calculation bug (#128) 2021-02-06 09:32:25 +01:00
81 changed files with 3507 additions and 225 deletions

View File

@ -33,3 +33,17 @@ jobs:
"and check in all changes" \
&& exit 1)
shell: bash
build_web_version:
name: Check that the web version compile
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: subosito/flutter-action@v1
with:
channel: 'beta'
- run: flutter config --enable-web
- run: flutter precache web
- run: flutter pub get
working-directory: example
- run: flutter build web
working-directory: example

View File

@ -1,3 +1,9 @@
## [1.0.0]
- Migrate to null safety
- Fix some rendering bugs
- Add an image delegate to dynamically change images
- Allow to use an imageProviderFactory with a zip file
## [0.7.1]
- Fix a crash for some lottie file with empty paths.

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@ -1,2 +1,3 @@
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
#include "Generated.xcconfig"

View File

@ -1,2 +1,3 @@
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
#include "Generated.xcconfig"

View File

@ -86,7 +86,7 @@ class _MyAppState extends State<MyApp> with TickerProviderStateMixin {
],
),
const SizedBox(height: 30),
RaisedButton(
ElevatedButton(
child: Text('Loop between frames'),
onPressed: () {
// Loop between 2 specifics frames

View File

@ -87,15 +87,15 @@ class _LottieDetailsState extends State<_LottieDetails>
title: Text('Composition duration'),
trailing: Text(widget.composition.durationFrames.toStringAsFixed(1)),
),
RaisedButton(
ElevatedButton(
child: Text('touchDownEnd - touchUpCancel'),
onPressed: () => _playBetween('touchDownEnd', 'touchUpCancel'),
),
RaisedButton(
ElevatedButton(
child: Text('touchDownStart - touchDownEnd'),
onPressed: () => _playBetween('touchDownStart', 'touchDownEnd'),
),
RaisedButton(
ElevatedButton(
child: Text('touchDownEnd - touchUpEnd'),
onPressed: () => _playBetween('touchDownEnd', 'touchUpEnd'),
),

View File

@ -28,7 +28,7 @@ class _MyAppState extends State<MyApp> {
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
RaisedButton(
ElevatedButton(
child: Text('Export all frames'),
onPressed: _export,
),

View File

@ -21,34 +21,36 @@ class App extends StatelessWidget {
appBar: AppBar(
title: Text('Lottie Flutter'),
),
body: GridView.builder(
itemCount: files.length,
gridDelegate:
SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 4),
itemBuilder: (context, index) {
var assetName = files[index];
return GestureDetector(
child: _Item(
child: Lottie.asset(
assetName,
frameBuilder: (context, child, composition) {
return AnimatedOpacity(
child: child,
opacity: composition == null ? 0 : 1,
duration: const Duration(seconds: 1),
curve: Curves.easeOut,
);
},
body: Scrollbar(
child: GridView.builder(
itemCount: files.length,
gridDelegate:
SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 4),
itemBuilder: (context, index) {
var assetName = files[index];
return GestureDetector(
child: _Item(
child: Lottie.asset(
assetName,
frameBuilder: (context, child, composition) {
return AnimatedOpacity(
child: child,
opacity: composition == null ? 0 : 1,
duration: const Duration(seconds: 1),
curve: Curves.easeOut,
);
},
),
),
),
onTap: () {
Navigator.push(
context,
MaterialPageRoute<void>(
builder: (context) => Detail(assetName)));
},
);
},
onTap: () {
Navigator.push(
context,
MaterialPageRoute<void>(
builder: (context) => Detail(assetName)));
},
);
},
),
),
),
);

View File

@ -1,2 +1,3 @@
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
#include "ephemeral/Flutter-Generated.xcconfig"

View File

@ -1,2 +1,3 @@
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
#include "ephemeral/Flutter-Generated.xcconfig"

View File

@ -1,27 +1,28 @@
PODS:
- FlutterMacOS (1.0.0)
- FlutterMacOS (1.22.4)
- path_provider (0.0.1)
- path_provider_macos (0.0.1):
- FlutterMacOS
DEPENDENCIES:
- FlutterMacOS (from `Flutter/ephemeral/.symlinks/flutter/darwin-x64-profile`)
- path_provider (from `Flutter/ephemeral/.symlinks/plugins/path_provider/macos`)
- path_provider_macos (from `Flutter/ephemeral/.symlinks/plugins/path_provider_macos/macos`)
SPEC REPOS:
trunk:
- FlutterMacOS
EXTERNAL SOURCES:
FlutterMacOS:
:path: Flutter/ephemeral/.symlinks/flutter/darwin-x64-profile
path_provider:
:path: Flutter/ephemeral/.symlinks/plugins/path_provider/macos
path_provider_macos:
:path: Flutter/ephemeral/.symlinks/plugins/path_provider_macos/macos
SPEC CHECKSUMS:
FlutterMacOS: 15bea8a44d2fa024068daa0140371c020b4b6ff9
FlutterMacOS: ac210ef71944b3f04789076d70d4c72c7ec0c619
path_provider: e0848572d1d38b9a7dd099e79cf83f5b7e2cde9f
path_provider_macos: a0a3fd666cb7cd0448e936fb4abad4052961002b
PODFILE CHECKSUM: d8ba9b3e9e93c62c74a660b46c6fcb09f03991a7
COCOAPODS: 1.10.0
COCOAPODS: 1.10.1

View File

@ -26,10 +26,6 @@
33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F22044A3C60003C045 /* Assets.xcassets */; };
33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F42044A3C60003C045 /* MainMenu.xib */; };
33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */; };
33D1A10422148B71006C7A3E /* FlutterMacOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 33D1A10322148B71006C7A3E /* FlutterMacOS.framework */; };
33D1A10522148B93006C7A3E /* FlutterMacOS.framework in Bundle Framework */ = {isa = PBXBuildFile; fileRef = 33D1A10322148B71006C7A3E /* FlutterMacOS.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
D73912F022F37F9E000D13A0 /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D73912EF22F37F9E000D13A0 /* App.framework */; };
D73912F222F3801D000D13A0 /* App.framework in Bundle Framework */ = {isa = PBXBuildFile; fileRef = D73912EF22F37F9E000D13A0 /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
F03CC91740A974D36C2A6384 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0BC6FF5FCD90624533CC60DB /* Pods_Runner.framework */; };
/* End PBXBuildFile section */
@ -50,8 +46,6 @@
dstPath = "";
dstSubfolderSpec = 10;
files = (
D73912F222F3801D000D13A0 /* App.framework in Bundle Framework */,
33D1A10522148B93006C7A3E /* FlutterMacOS.framework in Bundle Framework */,
);
name = "Bundle Framework";
runOnlyForDeploymentPostprocessing = 0;
@ -73,14 +67,12 @@
33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Debug.xcconfig"; sourceTree = "<group>"; };
33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Release.xcconfig"; sourceTree = "<group>"; };
33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "Flutter-Generated.xcconfig"; path = "ephemeral/Flutter-Generated.xcconfig"; sourceTree = "<group>"; };
33D1A10322148B71006C7A3E /* FlutterMacOS.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = FlutterMacOS.framework; path = Flutter/ephemeral/FlutterMacOS.framework; sourceTree = SOURCE_ROOT; };
33E51913231747F40026EE4D /* DebugProfile.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = DebugProfile.entitlements; sourceTree = "<group>"; };
33E51914231749380026EE4D /* Release.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = Release.entitlements; sourceTree = "<group>"; };
33E5194F232828860026EE4D /* AppInfo.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = AppInfo.xcconfig; sourceTree = "<group>"; };
5B4C0E87024EC2686CA05E23 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; };
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = "<group>"; };
9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = "<group>"; };
D73912EF22F37F9E000D13A0 /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/ephemeral/App.framework; sourceTree = SOURCE_ROOT; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@ -88,8 +80,6 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
D73912F022F37F9E000D13A0 /* App.framework in Frameworks */,
33D1A10422148B71006C7A3E /* FlutterMacOS.framework in Frameworks */,
F03CC91740A974D36C2A6384 /* Pods_Runner.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
@ -145,8 +135,6 @@
33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */,
33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */,
33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */,
D73912EF22F37F9E000D13A0 /* App.framework */,
33D1A10322148B71006C7A3E /* FlutterMacOS.framework */,
);
path = Flutter;
sourceTree = "<group>";
@ -281,7 +269,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "echo \"$PRODUCT_NAME.app\" > \"$PROJECT_DIR\"/Flutter/ephemeral/.app_filename\n";
shellScript = "echo \"$PRODUCT_NAME.app\" > \"$PROJECT_DIR\"/Flutter/ephemeral/.app_filename && \"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh embed\n";
};
33CC111E2044C6BF0003C045 /* ShellScript */ = {
isa = PBXShellScriptBuildPhase;

View File

@ -7,63 +7,63 @@ packages:
name: archive
url: "https://pub.dartlang.org"
source: hosted
version: "3.0.0-nullsafety.0"
version: "3.0.0"
async:
dependency: transitive
description:
name: async
url: "https://pub.dartlang.org"
source: hosted
version: "2.5.0-nullsafety.3"
version: "2.5.0"
boolean_selector:
dependency: transitive
description:
name: boolean_selector
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.0-nullsafety.3"
version: "2.1.0"
characters:
dependency: transitive
description:
name: characters
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.0-nullsafety.5"
version: "1.1.0"
charcode:
dependency: transitive
description:
name: charcode
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.0-nullsafety.3"
version: "1.2.0"
clock:
dependency: transitive
description:
name: clock
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.0-nullsafety.3"
version: "1.1.0"
collection:
dependency: transitive
description:
name: collection
url: "https://pub.dartlang.org"
source: hosted
version: "1.15.0-nullsafety.5"
version: "1.15.0"
crypto:
dependency: transitive
description:
name: crypto
url: "https://pub.dartlang.org"
source: hosted
version: "3.0.0-nullsafety.0"
version: "3.0.0"
fake_async:
dependency: transitive
description:
name: fake_async
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.0-nullsafety.3"
version: "1.2.0"
ffi:
dependency: transitive
description:
@ -129,35 +129,35 @@ packages:
name: logging
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.0-nullsafety.0"
version: "1.0.0"
lottie:
dependency: "direct main"
description:
path: ".."
relative: true
source: path
version: "0.8.0-nullsafety.0"
version: "1.0.0"
matcher:
dependency: transitive
description:
name: matcher
url: "https://pub.dartlang.org"
source: hosted
version: "0.12.10-nullsafety.3"
version: "0.12.10"
meta:
dependency: transitive
description:
name: meta
url: "https://pub.dartlang.org"
source: hosted
version: "1.3.0-nullsafety.6"
version: "1.3.0"
path:
dependency: transitive
description:
name: path
url: "https://pub.dartlang.org"
source: hosted
version: "1.8.0-nullsafety.3"
version: "1.8.0"
path_provider:
dependency: "direct main"
description:
@ -232,56 +232,56 @@ packages:
name: source_span
url: "https://pub.dartlang.org"
source: hosted
version: "1.8.0-nullsafety.4"
version: "1.8.0"
stack_trace:
dependency: transitive
description:
name: stack_trace
url: "https://pub.dartlang.org"
source: hosted
version: "1.10.0-nullsafety.6"
version: "1.10.0"
stream_channel:
dependency: transitive
description:
name: stream_channel
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.0-nullsafety.3"
version: "2.1.0"
string_scanner:
dependency: transitive
description:
name: string_scanner
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.0-nullsafety.3"
version: "1.1.0"
term_glyph:
dependency: transitive
description:
name: term_glyph
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.0-nullsafety.3"
version: "1.2.0"
test_api:
dependency: transitive
description:
name: test_api
url: "https://pub.dartlang.org"
source: hosted
version: "0.2.19-nullsafety.6"
version: "0.2.19"
typed_data:
dependency: transitive
description:
name: typed_data
url: "https://pub.dartlang.org"
source: hosted
version: "1.3.0-nullsafety.5"
version: "1.3.0"
vector_math:
dependency: transitive
description:
name: vector_math
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.0-nullsafety.5"
version: "2.1.0"
win32:
dependency: transitive
description:
@ -298,4 +298,4 @@ packages:
version: "0.1.2"
sdks:
dart: ">=2.12.0-29.10.beta <3.0.0"
flutter: ">=1.24.0-10.2.pre <2.0.0"
flutter: ">=1.24.0-10.2.pre"

View File

@ -0,0 +1,74 @@
import 'dart:async';
import 'dart:io';
import 'dart:ui' as ui;
import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:lottie/lottie.dart';
import 'utils.dart';
void main() {
testWidgets('Can specify ImageProvider with zip file ', (tester) async {
var size = Size(500, 400);
tester.binding.window.physicalSizeTestValue = size;
tester.binding.window.devicePixelRatioTestValue = 1.0;
var callCount = 0;
LottieImageProviderFactory imageProviderFactory = (image) {
++callCount;
return FileImage(File('assets/Images/WeAccept/img_0.png'));
};
var composition = (await tester.runAsync(() => FileLottie(
File('assets/spinning_carrousel.zip'),
imageProviderFactory: imageProviderFactory)
.load()))!;
await tester.pumpWidget(FilmStrip(composition, size: size));
expect(callCount, 2);
await expectLater(find.byType(FilmStrip),
matchesGoldenFile('goldens/dynamic_image/zip_with_provider.png'));
});
testWidgets('Can specify image delegate', (tester) async {
var size = Size(500, 400);
tester.binding.window.physicalSizeTestValue = size;
tester.binding.window.devicePixelRatioTestValue = 1.0;
var image = await tester.runAsync(
() => loadImage(FileImage(File('assets/Images/WeAccept/img_0.png'))));
var composition = (await tester.runAsync(
() => FileLottie(File('assets/spinning_carrousel.zip')).load()))!;
var delegates = LottieDelegates(image: (composition, asset) {
return image;
});
await tester.pumpWidget(FilmStrip(
composition,
size: size,
delegates: delegates,
));
await expectLater(find.byType(FilmStrip),
matchesGoldenFile('goldens/dynamic_image/delegate.png'));
});
}
Future<ui.Image?> loadImage(ImageProvider provider) {
var completer = Completer<ui.Image?>();
var imageStream = provider.resolve(ImageConfiguration.empty);
late ImageStreamListener listener;
listener = ImageStreamListener((image, synchronousLoaded) {
imageStream.removeListener(listener);
completer.complete(image.image);
}, onError: (dynamic e, __) {
imageStream.removeListener(listener);
completer.complete();
});
imageStream.addListener(listener);
return completer.future;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.5 KiB

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.2 KiB

After

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 884 B

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.6 KiB

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 62 KiB

After

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 53 KiB

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.5 KiB

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 58 KiB

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 65 KiB

After

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 KiB

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.0 KiB

After

Width:  |  Height:  |  Size: 8.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

View File

@ -9,6 +9,7 @@ export 'src/model/marker.dart' show Marker;
export 'src/options.dart' show LottieOptions;
export 'src/providers/asset_provider.dart' show AssetLottie;
export 'src/providers/file_provider.dart' show FileLottie;
export 'src/providers/load_image.dart' show LottieImageProviderFactory;
export 'src/providers/lottie_provider.dart' show LottieProvider;
export 'src/providers/memory_provider.dart' show MemoryLottie;
export 'src/providers/network_provider.dart' show NetworkLottie;

View File

@ -241,11 +241,9 @@ abstract class BaseStrokeContent
var bounds = _path.getBounds();
var width = _widthAnimation.value;
bounds = Rect.fromLTWH(bounds.left - width / 2.0, bounds.top - width / 2.0,
bounds.right + width / 2.0, bounds.bottom + width / 2.0);
bounds = bounds.inflate(width / 2.0);
// Add padding to account for rounding errors.
bounds = Rect.fromLTWH(
bounds.left - 1, bounds.top - 1, bounds.right + 1, bounds.bottom + 1);
bounds = bounds.inflate(1);
L.endSection('StrokeContent#getBounds');
return bounds;
}

View File

@ -102,8 +102,7 @@ class FillContent implements DrawingContent, KeyPathElementContent {
}
var outBounds = _path.getBounds();
// Add padding to account for rounding errors.
outBounds = Rect.fromLTWH(outBounds.left - 1, outBounds.top - 1,
outBounds.right + 1, outBounds.bottom + 1);
outBounds = outBounds.inflate(1);
return outBounds;
}

View File

@ -127,8 +127,7 @@ class GradientFillContent implements DrawingContent, KeyPathElementContent {
var outBounds = _path.getBounds();
// Add padding to account for rounding errors.
return Rect.fromLTWH(outBounds.left - 1, outBounds.top - 1,
outBounds.right + 1, outBounds.bottom + 1);
return outBounds.inflate(1);
}
Gradient _getLinearGradient() {

View File

@ -34,12 +34,14 @@ class CompositionParameters {
}
class LottieComposition {
static Future<LottieComposition> fromByteData(ByteData data, {String? name}) {
return fromBytes(data.buffer.asUint8List(), name: name);
static Future<LottieComposition> fromByteData(ByteData data,
{String? name, LottieImageProviderFactory? imageProviderFactory}) {
return fromBytes(data.buffer.asUint8List(),
name: name, imageProviderFactory: imageProviderFactory);
}
static Future<LottieComposition> fromBytes(Uint8List bytes,
{String? name}) async {
{String? name, LottieImageProviderFactory? imageProviderFactory}) async {
Archive? archive;
if (bytes[0] == 0x50 && bytes[1] == 0x4B) {
archive = ZipDecoder().decodeBytes(bytes);
@ -55,8 +57,18 @@ class LottieComposition {
var imagePath = p.posix.join(image.dirName, image.fileName);
var found = archive.files.firstWhereOrNull(
(f) => f.name.toLowerCase() == imagePath.toLowerCase());
ImageProvider? provider;
if (imageProviderFactory != null) {
provider = imageProviderFactory(image);
}
if (provider != null) {
image.loadedImage = await loadImage(composition, image, provider);
}
if (found != null) {
image.loadedImage = await loadImage(
image.loadedImage ??= await loadImage(
composition, image, MemoryImage(found.content as Uint8List));
}
}

View File

@ -381,14 +381,11 @@ class _LottieBuilderState extends State<LottieBuilder> {
void _load() {
var provider = widget.lottie;
_loadingFuture = widget.lottie.load().then((composition) {
print('Loaded');
if (mounted && widget.onLoaded != null && widget.lottie == provider) {
widget.onLoaded!(composition);
}
return composition;
}, onError: (Object e, StackTrace t) {
print('Load error $e $t');
});
}

View File

@ -1,4 +1,6 @@
import 'dart:ui' as ui;
import 'package:flutter/widgets.dart';
import '../lottie.dart';
import 'lottie_drawable.dart';
import 'value_delegate.dart';
@ -43,12 +45,31 @@ class LottieDelegates {
/// ```
final List<ValueDelegate>? values;
//TODO(xha): imageDelegate to change the image to display?
/// A callback to dynamically change an image of the animation.
///
/// Example:
/// ```dart
/// Lottie.asset(
// 'assets/data.json',
// delegates: LottieDelegates(
// image: (composition, image) {
// if (image.id == 'img_0' && _isMouseOver) {
// return myCustomImage;
// }
//
// // Use the default method: composition.images[image.id].loadedImage;
// return null;
// },
// )
// )
/// ```
final ui.Image? Function(LottieComposition, LottieImageAsset)? image;
LottieDelegates({
this.text,
TextStyle Function(LottieFontStyle)? textStyle,
this.values,
this.image,
}) : textStyle = textStyle;
@override

View File

@ -79,7 +79,13 @@ class LottieDrawable {
ui.Image? getImageAsset(String? ref) {
var imageAsset = composition.images[ref];
if (imageAsset != null) {
return imageAsset.loadedImage;
var imageDelegate = delegates?.image;
ui.Image? image;
if (imageDelegate != null) {
image = imageDelegate(composition, imageAsset);
}
return image ?? imageAsset.loadedImage;
} else {
return null;
}

View File

@ -31,7 +31,7 @@ abstract class BaseLayer implements DrawingContent, KeyPathElement {
static BaseLayer? forModel(Layer layerModel, LottieDrawable drawable,
LottieComposition composition) {
switch (layerModel.layerType) {
case LayerType.shap:
case LayerType.shape:
return ShapeLayer(drawable, layerModel);
case LayerType.preComp:
return CompositionLayer(drawable, layerModel,
@ -197,11 +197,11 @@ abstract class BaseLayer implements DrawingContent, KeyPathElement {
var bounds = getBounds(_matrix, applyParents: false);
// Uncomment this to draw matte outlines.
/* Paint paint = new LPaint();
paint.setColor(Color.RED);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(3);
canvas.drawRect(rect, paint); */
/*var paint = Paint()
..color = Color(0xFF00FF00)
..style = PaintingStyle.stroke
..strokeWidth = 3;
canvas.drawRect(bounds, paint);*/
bounds = _intersectBoundsWithMatte(bounds, parentMatrix);
@ -261,10 +261,7 @@ abstract class BaseLayer implements DrawingContent, KeyPathElement {
void _clearCanvas(Canvas canvas, Rect bounds) {
L.beginSection('Layer#clearLayer');
// If we don't pad the clear draw, some phones leave a 1px border of the graphics buffer.
canvas.drawRect(
Rect.fromLTRB(bounds.left - 1, bounds.top - 1, bounds.right + 1,
bounds.bottom + 1),
_clearPaint);
canvas.drawRect(bounds.inflate(1), _clearPaint);
L.endSection('Layer#clearLayer');
}

View File

@ -8,7 +8,7 @@ import '../animatable/animatable_transform.dart';
import '../content/content_model.dart';
import '../content/mask.dart';
enum LayerType { preComp, solid, image, nullLayer, shap, text, unknown }
enum LayerType { preComp, solid, image, nullLayer, shape, text, unknown }
enum MatteType { none, add, invert, unknown }

View File

@ -101,13 +101,12 @@ class LottieCompositionParser {
}
layers.add(layer);
layerMap[layer.id] = layer;
if (imageCount > 4) {
composition.addWarning(
'You have $imageCount images. Lottie should primarily be '
'used with shapes. If you are using Adobe Illustrator, convert the Illustrator layers'
' to shape layers.');
}
}
if (imageCount > 4) {
composition.addWarning(
'You have $imageCount images. Lottie should primarily be '
'used with shapes. If you are using Adobe Illustrator, convert the Illustrator layers'
' to shape layers.');
}
reader.endArray();
}

View File

@ -33,7 +33,8 @@ class AssetLottie extends LottieProvider {
var data = await chosenBundle.load(keyName);
var composition = await LottieComposition.fromByteData(data,
name: p.url.basenameWithoutExtension(keyName));
name: p.url.basenameWithoutExtension(keyName),
imageProviderFactory: imageProviderFactory);
for (var image in composition.images.values) {
image.loadedImage ??= await _loadImage(composition, image);

View File

@ -18,7 +18,8 @@ class FileLottie extends LottieProvider {
return sharedLottieCache.putIfAbsent(cacheKey, () async {
var bytes = await io.loadFile(file);
var composition = await LottieComposition.fromBytes(bytes,
name: p.basenameWithoutExtension(io.filePath(file)));
name: p.basenameWithoutExtension(io.filePath(file)),
imageProviderFactory: imageProviderFactory);
for (var image in composition.images.values) {
image.loadedImage ??= await _loadImage(composition, image);

View File

@ -4,7 +4,7 @@ import 'package:flutter/widgets.dart';
import '../composition.dart';
import '../lottie_image_asset.dart';
typedef LottieImageProviderFactory = ImageProvider Function(LottieImageAsset);
typedef LottieImageProviderFactory = ImageProvider? Function(LottieImageAsset);
Future<ui.Image?> loadImage(LottieComposition composition,
LottieImageAsset lottieImage, ImageProvider provider) {

View File

@ -18,7 +18,8 @@ class MemoryLottie extends LottieProvider {
// TODO(xha): hash the list content
var cacheKey = 'memory-${bytes.hashCode}-${bytes.lengthInBytes}';
return sharedLottieCache.putIfAbsent(cacheKey, () async {
var composition = await LottieComposition.fromBytes(bytes);
var composition = await LottieComposition.fromBytes(bytes,
imageProviderFactory: imageProviderFactory);
for (var image in composition.images.values) {
image.loadedImage ??= await _loadImage(composition, image);
}

View File

@ -24,7 +24,8 @@ class NetworkLottie extends LottieProvider {
var bytes = await network.loadHttp(resolved, headers: headers);
var composition = await LottieComposition.fromBytes(bytes,
name: p.url.basenameWithoutExtension(url));
name: p.url.basenameWithoutExtension(url),
imageProviderFactory: imageProviderFactory);
for (var image in composition.images.values) {
image.loadedImage ??= await _loadImage(resolved, composition, image);

View File

@ -30,6 +30,6 @@ String filePath(Object file) {
return (file as File).relativePath ?? '';
}
ImageProvider? loadImageForFile(Object file, LottieImageAsset lottieImage) {
return null;
ImageProvider loadImageForFile(Object file, LottieImageAsset lottieImage) {
throw UnimplementedError();
}

View File

@ -7,112 +7,112 @@ packages:
name: _fe_analyzer_shared
url: "https://pub.dartlang.org"
source: hosted
version: "14.0.0"
version: "16.0.0"
analyzer:
dependency: "direct dev"
description:
name: analyzer
url: "https://pub.dartlang.org"
source: hosted
version: "0.41.2"
version: "1.0.0"
archive:
dependency: "direct main"
description:
name: archive
url: "https://pub.dartlang.org"
source: hosted
version: "3.0.0-nullsafety.0"
version: "3.0.0"
args:
dependency: transitive
description:
name: args
url: "https://pub.dartlang.org"
source: hosted
version: "1.6.0"
version: "2.0.0"
async:
dependency: transitive
description:
name: async
url: "https://pub.dartlang.org"
source: hosted
version: "2.5.0-nullsafety.3"
version: "2.5.0"
boolean_selector:
dependency: transitive
description:
name: boolean_selector
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.0-nullsafety.3"
version: "2.1.0"
build:
dependency: transitive
description:
name: build
url: "https://pub.dartlang.org"
source: hosted
version: "1.6.1"
version: "1.6.3"
build_config:
dependency: transitive
description:
name: build_config
url: "https://pub.dartlang.org"
source: hosted
version: "0.4.5"
version: "0.4.6"
build_daemon:
dependency: transitive
description:
name: build_daemon
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.6"
version: "2.1.8"
build_resolvers:
dependency: transitive
description:
name: build_resolvers
url: "https://pub.dartlang.org"
source: hosted
version: "1.5.2"
version: "1.5.4"
build_runner:
dependency: "direct dev"
description:
name: build_runner
url: "https://pub.dartlang.org"
source: hosted
version: "1.11.0"
version: "1.11.5"
build_runner_core:
dependency: transitive
description:
name: build_runner_core
url: "https://pub.dartlang.org"
source: hosted
version: "6.1.6"
version: "6.1.10"
built_collection:
dependency: transitive
description:
name: built_collection
url: "https://pub.dartlang.org"
source: hosted
version: "4.3.2"
version: "5.0.0"
built_value:
dependency: transitive
description:
name: built_value
url: "https://pub.dartlang.org"
source: hosted
version: "7.1.0"
version: "8.0.0"
characters:
dependency: "direct main"
description:
name: characters
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.0-nullsafety.5"
version: "1.1.0"
charcode:
dependency: "direct main"
description:
name: charcode
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.0-nullsafety.3"
version: "1.2.0"
checked_yaml:
dependency: transitive
description:
@ -126,14 +126,14 @@ packages:
name: cli_util
url: "https://pub.dartlang.org"
source: hosted
version: "0.2.0"
version: "0.3.0"
clock:
dependency: transitive
description:
name: clock
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.0-nullsafety.3"
version: "1.1.0"
code_builder:
dependency: transitive
description:
@ -147,49 +147,49 @@ packages:
name: collection
url: "https://pub.dartlang.org"
source: hosted
version: "1.15.0-nullsafety.5"
version: "1.15.0"
convert:
dependency: transitive
description:
name: convert
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.1"
version: "3.0.0"
crypto:
dependency: transitive
description:
name: crypto
url: "https://pub.dartlang.org"
source: hosted
version: "3.0.0-nullsafety.0"
version: "3.0.0"
dart_style:
dependency: "direct dev"
description:
name: dart_style
url: "https://pub.dartlang.org"
source: hosted
version: "1.3.11"
version: "1.3.13"
fake_async:
dependency: transitive
description:
name: fake_async
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.0-nullsafety.3"
version: "1.2.0"
file:
dependency: transitive
description:
name: file
url: "https://pub.dartlang.org"
source: hosted
version: "5.2.1"
version: "6.1.0"
fixnum:
dependency: transitive
description:
name: fixnum
url: "https://pub.dartlang.org"
source: hosted
version: "0.10.11"
version: "1.0.0"
flutter:
dependency: "direct main"
description: flutter
@ -206,7 +206,7 @@ packages:
name: glob
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.0"
version: "2.0.0"
graphs:
dependency: transitive
description:
@ -227,14 +227,7 @@ packages:
name: http_parser
url: "https://pub.dartlang.org"
source: hosted
version: "3.1.4"
intl:
dependency: transitive
description:
name: intl
url: "https://pub.dartlang.org"
source: hosted
version: "0.16.1"
version: "4.0.0"
io:
dependency: transitive
description:
@ -248,126 +241,107 @@ packages:
name: js
url: "https://pub.dartlang.org"
source: hosted
version: "0.6.2"
version: "0.6.3"
json_annotation:
dependency: transitive
description:
name: json_annotation
url: "https://pub.dartlang.org"
source: hosted
version: "3.1.1"
version: "4.0.0"
logging:
dependency: "direct main"
description:
name: logging
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.0-nullsafety.0"
version: "1.0.0"
matcher:
dependency: transitive
description:
name: matcher
url: "https://pub.dartlang.org"
source: hosted
version: "0.12.10-nullsafety.3"
version: "0.12.10"
meta:
dependency: "direct main"
description:
name: meta
url: "https://pub.dartlang.org"
source: hosted
version: "1.3.0-nullsafety.6"
version: "1.3.0"
mime:
dependency: transitive
description:
name: mime
url: "https://pub.dartlang.org"
source: hosted
version: "0.9.7"
version: "1.0.0"
mockito:
dependency: "direct dev"
description:
name: mockito
url: "https://pub.dartlang.org"
source: hosted
version: "5.0.0-nullsafety.5"
node_interop:
dependency: transitive
description:
name: node_interop
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.1"
node_io:
dependency: transitive
description:
name: node_io
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.0"
path: "."
ref: c9fa227
resolved-ref: c9fa2276b6b352331105e5b000d60f996d8ec452
url: "https://github.com/dart-lang/mockito.git"
source: git
version: "5.0.0"
package_config:
dependency: transitive
description:
name: package_config
url: "https://pub.dartlang.org"
source: hosted
version: "1.9.3"
version: "2.0.0"
path:
dependency: "direct main"
description:
name: path
url: "https://pub.dartlang.org"
source: hosted
version: "1.8.0-nullsafety.3"
version: "1.8.0"
pedantic:
dependency: transitive
description:
name: pedantic
url: "https://pub.dartlang.org"
source: hosted
version: "1.9.2"
version: "1.10.0"
pool:
dependency: transitive
description:
name: pool
url: "https://pub.dartlang.org"
source: hosted
version: "1.4.0"
version: "1.5.0"
pub_semver:
dependency: transitive
dependency: "direct dev"
description:
name: pub_semver
url: "https://pub.dartlang.org"
source: hosted
version: "1.4.4"
version: "2.0.0"
pubspec_parse:
dependency: transitive
description:
name: pubspec_parse
url: "https://pub.dartlang.org"
source: hosted
version: "0.1.7"
quiver:
dependency: transitive
description:
name: quiver
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.5"
version: "0.1.8"
shelf:
dependency: transitive
description:
name: shelf
url: "https://pub.dartlang.org"
source: hosted
version: "0.7.9"
version: "1.0.0"
shelf_web_socket:
dependency: transitive
description:
name: shelf_web_socket
url: "https://pub.dartlang.org"
source: hosted
version: "0.2.3"
version: "0.2.4+1"
sky_engine:
dependency: transitive
description: flutter
@ -379,56 +353,56 @@ packages:
name: source_gen
url: "https://pub.dartlang.org"
source: hosted
version: "0.9.10+1"
version: "0.9.10+3"
source_span:
dependency: transitive
description:
name: source_span
url: "https://pub.dartlang.org"
source: hosted
version: "1.8.0-nullsafety.4"
version: "1.8.0"
stack_trace:
dependency: transitive
description:
name: stack_trace
url: "https://pub.dartlang.org"
source: hosted
version: "1.10.0-nullsafety.6"
version: "1.10.0"
stream_channel:
dependency: transitive
description:
name: stream_channel
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.0-nullsafety.3"
version: "2.1.0"
stream_transform:
dependency: transitive
description:
name: stream_transform
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.0"
version: "2.0.0"
string_scanner:
dependency: transitive
description:
name: string_scanner
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.0-nullsafety.3"
version: "1.1.0"
term_glyph:
dependency: transitive
description:
name: term_glyph
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.0-nullsafety.3"
version: "1.2.0"
test_api:
dependency: transitive
description:
name: test_api
url: "https://pub.dartlang.org"
source: hosted
version: "0.2.19-nullsafety.6"
version: "0.2.19"
timing:
dependency: transitive
description:
@ -442,21 +416,21 @@ packages:
name: typed_data
url: "https://pub.dartlang.org"
source: hosted
version: "1.3.0-nullsafety.5"
version: "1.3.0"
vector_math:
dependency: "direct main"
description:
name: vector_math
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.0-nullsafety.5"
version: "2.1.0"
watcher:
dependency: transitive
description:
name: watcher
url: "https://pub.dartlang.org"
source: hosted
version: "0.9.7+15"
version: "1.0.0"
web_socket_channel:
dependency: transitive
description:
@ -470,6 +444,6 @@ packages:
name: yaml
url: "https://pub.dartlang.org"
source: hosted
version: "2.2.1"
version: "3.0.0"
sdks:
dart: ">=2.12.0-0.0 <3.0.0"

View File

@ -1,28 +1,32 @@
name: lottie
description: Render After Effects animations natively on Flutter. This package is a pure Dart implementation of a Lottie player.
version: 0.8.0-nullsafety.0
version: 1.0.0
homepage: https://github.com/xvrh/lottie-flutter
environment:
sdk: '>=2.12.0-0 <3.0.0'
dependencies:
archive: ^3.0.0-nullsafety.0
characters: ^1.0.0-nullsafety.0
charcode: ^1.2.0-nullsafety.0
collection: ^1.15.0-nullsafety.0
archive: ^3.0.0
characters: ^1.1.0
charcode: ^1.2.0
collection: ^1.15.0
flutter:
sdk: flutter
logging: ^1.0.0-nullsafety.0
meta: ^1.3.0-nullsafety.0
path: ^1.8.0-nullsafety.0
vector_math: ^2.0.0-nullsafety.0
logging: ^1.0.0
meta: ^1.3.0
path: ^1.8.0
vector_math: ^2.1.0
dev_dependencies:
analyzer:
analyzer: ^1.0.0
build_runner:
dart_style:
flutter_test:
sdk: flutter
mockito: ^5.0.0-nullsafety.1
yaml:
mockito:
git:
url: https://github.com/dart-lang/mockito.git
ref: c9fa227
pub_semver:
yaml: ^3.0.0

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 31 KiB

View File

@ -1,10 +1,13 @@
// Mocks generated by Mockito 5.0.0-nullsafety.7 from annotations
// in lottie/test/lottie_test.dart.
// Do not manually edit this file.
import 'dart:async' as _i4;
import 'dart:typed_data' as _i2;
import 'package:flutter/src/services/asset_bundle.dart' as _i3;
import 'package:mockito/mockito.dart' as _i1;
// ignore_for_file: comment_references
// ignore_for_file: unnecessary_parenthesis
class _FakeByteData extends _i1.Fake implements _i2.ByteData {}
@ -19,22 +22,23 @@ class MockAssetBundle extends _i1.Mock implements _i3.AssetBundle {
@override
_i4.Future<_i2.ByteData> load(String? key) => (super.noSuchMethod(
Invocation.method(#load, [key]), Future.value(_FakeByteData()))
as _i4.Future<_i2.ByteData>);
Invocation.method(#load, [key]),
returnValue: Future.value(_FakeByteData())) as _i4.Future<_i2.ByteData>);
@override
_i4.Future<String> loadString(String? key, {bool? cache = true}) =>
(super.noSuchMethod(
Invocation.method(#loadString, [key], {#cache: cache}),
Future.value('')) as _i4.Future<String>);
_i4.Future<String> loadString(String? key, {bool? cache = true}) => (super
.noSuchMethod(Invocation.method(#loadString, [key], {#cache: cache}),
returnValue: Future.value('')) as _i4.Future<String>);
@override
_i4.Future<T> loadStructuredData<T>(
String? key, _i4.Future<T> Function(String)? parser) =>
(super.noSuchMethod(Invocation.method(#loadStructuredData, [key, parser]),
Future.value(null)) as _i4.Future<T>);
returnValue: Future.value(null)) as _i4.Future<T>);
@override
void evict(String? key) =>
super.noSuchMethod(Invocation.method(#evict, [key]));
super.noSuchMethod(Invocation.method(#evict, [key]),
returnValueForMissingStub: null);
@override
String toString() =>
(super.noSuchMethod(Invocation.method(#toString, []), '') as String);
(super.noSuchMethod(Invocation.method(#toString, []), returnValue: '')
as String);
}