diff --git a/packages/vector_graphics/CHANGELOG.md b/packages/vector_graphics/CHANGELOG.md index 4367b1451186..a839b37646da 100644 --- a/packages/vector_graphics/CHANGELOG.md +++ b/packages/vector_graphics/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.1.18 + +* Allow transition between placeholder and loaded image to have an animation. + ## 1.1.17 * Reverts leaker tracker changes that caused runtime exceptions. diff --git a/packages/vector_graphics/lib/src/vector_graphics.dart b/packages/vector_graphics/lib/src/vector_graphics.dart index c849a81dd09d..f43990fdab83 100644 --- a/packages/vector_graphics/lib/src/vector_graphics.dart +++ b/packages/vector_graphics/lib/src/vector_graphics.dart @@ -61,6 +61,7 @@ VectorGraphic createCompatVectorGraphic({ String? semanticsLabel, bool excludeFromSemantics = false, Clip clipBehavior = Clip.hardEdge, + Duration? transitionDuration, WidgetBuilder? placeholderBuilder, VectorGraphicsErrorWidget? errorBuilder, ColorFilter? colorFilter, @@ -79,6 +80,7 @@ VectorGraphic createCompatVectorGraphic({ semanticsLabel: semanticsLabel, excludeFromSemantics: excludeFromSemantics, clipBehavior: clipBehavior, + transitionDuration: transitionDuration, placeholderBuilder: placeholderBuilder, errorBuilder: errorBuilder, colorFilter: colorFilter, @@ -118,6 +120,7 @@ class VectorGraphic extends StatefulWidget { this.semanticsLabel, this.excludeFromSemantics = false, this.clipBehavior = Clip.hardEdge, + this.transitionDuration, this.placeholderBuilder, this.errorBuilder, this.colorFilter, @@ -137,6 +140,7 @@ class VectorGraphic extends StatefulWidget { this.semanticsLabel, this.excludeFromSemantics = false, this.clipBehavior = Clip.hardEdge, + this.transitionDuration, this.placeholderBuilder, this.errorBuilder, this.colorFilter, @@ -218,6 +222,9 @@ class VectorGraphic extends StatefulWidget { /// A callback that fires if some exception happens during data acquisition or decoding. final VectorGraphicsErrorWidget? errorBuilder; + /// Set transition duration while switching from placeholder to url image + final Duration? transitionDuration; + /// If provided, a color filter to apply to the vector graphic when painting. /// /// For example, `ColorFilter.mode(Colors.red, BlendMode.srcIn)` to give the vector @@ -517,6 +524,19 @@ class _VectorGraphicWidgetState extends State { ); } + if (widget.transitionDuration != null) { + child = AnimatedSwitcher( + duration: widget.transitionDuration!, + child: child, + transitionBuilder: (Widget child, Animation animation) { + return FadeTransition( + opacity: animation, + child: child, + ); + }, + ); + } + if (!widget.excludeFromSemantics) { child = Semantics( container: widget.semanticsLabel != null, diff --git a/packages/vector_graphics/pubspec.yaml b/packages/vector_graphics/pubspec.yaml index 688f3bf93c58..67d3f0ed3d3a 100644 --- a/packages/vector_graphics/pubspec.yaml +++ b/packages/vector_graphics/pubspec.yaml @@ -2,7 +2,7 @@ name: vector_graphics description: A vector graphics rendering package for Flutter using a binary encoding. repository: https://github.com/flutter/packages/tree/main/packages/vector_graphics issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+vector_graphics%22 -version: 1.1.17 +version: 1.1.18 environment: sdk: ^3.4.0 diff --git a/packages/vector_graphics/test/vector_graphics_test.dart b/packages/vector_graphics/test/vector_graphics_test.dart index 8d8bc7fcb12b..6777355e44b2 100644 --- a/packages/vector_graphics/test/vector_graphics_test.dart +++ b/packages/vector_graphics/test/vector_graphics_test.dart @@ -314,6 +314,32 @@ void main() { expect(debugLastTextDirection, TextDirection.ltr); }); + testWidgets('Test animated switch between placeholder and image', + (WidgetTester tester) async { + final TestAssetBundle testBundle = TestAssetBundle(); + const Text placeholderWidget = Text('Placeholder'); + + await tester.pumpWidget(DefaultAssetBundle( + bundle: testBundle, + child: Directionality( + textDirection: TextDirection.rtl, + child: VectorGraphic( + loader: const AssetBytesLoader('bar.svg'), + placeholderBuilder: (BuildContext context) => placeholderWidget, + transitionDuration: const Duration(microseconds: 500), + ), + ), + )); + + expect(find.text('Placeholder'), findsOneWidget); + expect(find.byType(Container), findsNothing); // No image yet + + await tester.pumpAndSettle(const Duration(microseconds: 500)); + + expect(find.text('Placeholder'), findsNothing); + expect(testBundle.loadKeys, ['bar.svg']); + }); + testWidgets('Can exclude from semantics', (WidgetTester tester) async { final TestAssetBundle testBundle = TestAssetBundle();