Extensible Vector Graphics (SVG) is one of the most widely used file image formats in applications. Because it has several advantages over bitmap files, especially in preserving image quality when scaling, it would be difficult to start building a Flutter application without first considering using SVG.
In this article, you will learn how and when to use SVG files in a Flutter application.
Use SVG in Flutter
Skia, a 2D graphics library and the core component of Flutter, can only serialize images to SVG files. Therefore, decoding or rendering SVG images with Skia is not possible. Fortunately, the community came to the rescue with a fantastic Dart native package called Flutter_SVG that quickly renders and decodes SVG.
What is Flutter_SVG?
The Flutter_SVG package implements an image cache and stores a UI :Picture class. This is the SkPicture wrapper for the Skia graphics engine, which records specific SVG rendering commands in binary mode.
The UI.picture class does not consume much memory and is cached to avoid repeated parsing of XML files. Let’s look at the constructor for svgpicture. asset.
SvgPicture.asset(
String assetName, {
Key? key,
this.matchTextDirection = false,
AssetBundle? bundle,
String? package,
this.width,
this.height,
this.fit = BoxFit.contain,
this.alignment = Alignment.center,
this.allowDrawingOutsideViewBox = false,
this.placeholderBuilder,
Color? color,
BlendMode colorBlendMode = BlendMode.srcIn,
this.semanticsLabel,
this.excludeFromSemantics = false,
this.clipBehavior = Clip.hardEdge,
this.cacheColorFilter = false,
}) : pictureProvider = ExactAssetPicture(
allowDrawingOutsideViewBox == true
? svgStringDecoderOutsideViewBox
: svgStringDecoder,
assetName,
bundle: bundle,
package: package,
colorFilter: svg.cacheColorFilterOverride ?? cacheColorFilter
? _getColorFilter(color, colorBlendMode)
: null,
),
colorFilter = _getColorFilter(color, colorBlendMode),
super(key: key);
Copy the code
By observing the implementation, you’ll notice that the flow notification from pictureProvider updates the SvgPicture picture.
void _resolveImage() { final PictureStream newStream = widget.pictureProvider .resolve(createLocalPictureConfiguration(context)); assert(newStream ! = null); // ignore: unnecessary_null_comparison _updateSourceStream(newStream); }Copy the code
In this code block, the stream from pictureProvider is populated into UI.picture by the finisher of the image cache.
PictureStream resolve(PictureConfiguration picture, {PictureErrorListener? onError}) { // ignore: unnecessary_null_comparison assert(picture ! = null); final PictureStream stream = PictureStream(); T? obtainedKey; obtainKey(picture).then<void>( (T key) { obtainedKey = key; stream.setCompleter( cache.putIfAbsent( key! , () => load(key, onError: onError), ), ); }, ).catchError((Object exception, StackTrace stack) async { if (onError ! = null) { onError(exception, stack); return; } FlutterError.reportError(FlutterErrorDetails( exception: exception, stack: stack, library: 'SVG', context: ErrorDescription('while resolving a picture'), silent: true, // could be a network error or whatnot informationCollector: () sync* { yield DiagnosticsProperty<PictureProvider>( 'Picture provider', this); yield DiagnosticsProperty<T>('Picture key', obtainedKey, defaultValue: null); })); }); return stream; }Copy the code
Add the flutter_SVG plug-in
To add this package to your Flutter dependencies, you run.
flutter pub add flutter_svg
Copy the code
Alternatively, you can add Flutter_SVG to your pubspec.yaml file.
Dependencies: flutter_svg: ^ 0.22.0Copy the code
Make sure you run the flutter pub get on your terminal or using your editor. Once the installation is complete, import the package where you want to use it in your Dart code.
import 'package:flutter_svg/flutter_svg.dart';
Copy the code
Use Flutter_SVG in your Flutter application
There are several ways to use this package, but we’ll cover the most common use cases.
One option is to load SVG from an internal SVG file, which is typically stored in the Asset folder.
// example
final String assetName = 'assets/image.svg';
final Widget svg = SvgPicture.asset(
assetName,
);
Copy the code
You can also load an SVG file from a URL like this.
// example
final Widget networkSvg = SvgPicture.network(
'https://site-that-takes-a-while.com/image.svg',
);
Copy the code
Finally, you can load an SVG from an SVG code.
// example SvgPicture.string( '''<svg viewBox="..." >... </svg>''' );Copy the code
Extend SVG functionality in Flutter
Once you load your SVG file, the first step is to change the color or hue of the image.
// example
final String assetName = 'assets/up_arrow.svg';
final Widget svgIcon = SvgPicture.asset(
assetName,
color: Colors.red,
);
Copy the code
Using semantic tags helps describe the purpose of the image and enhances accessibility. To do this, you can add the semanticsLabel parameter. Semantic labels will not be displayed in the user interface.
// example
final String assetName = 'assets/up_arrow.svg';
final Widget svgIcon = SvgPicture.asset(
assetName,
color: Colors.red,
semanticsLabel: 'A red up arrow'
);
Copy the code
SvgPicture If height or width is not specified, the Flutter_SVG package renders an empty box, LimitedBox, as the default placeholder. However, if SvgPicture is specified on height or width, a SizedBox is rendered to ensure a better layout experience.
However, placeholders can be replaced, which is great for improving the user experience, especially when there may be delays in loading assets through network requests.
// example final Widget networkSvg = SvgPicture.network( 'https://site-that-takes-a-while.com/image.svg', semanticsLabel: 'A shark?! ', placeholderBuilder: (BuildContext context) => Container(padding: const EdgeInsets. All), child: const CircularProgressIndicator()), );Copy the code
In this case, I chose CircularProgressIndicator, when you load in the picture display a progress indicator. You can add any other widget you want. For example, you can use a custom load components to replace CircularProgressIndicator.
Check SVG compatibility with Flutter_SVG
You should know that the Flutter_SVG library does not support all SVG capabilities. However, the package does provide a helper method to ensure you don’t render a broken image due to a lack of supported features.
// example
final SvgParser parser = SvgParser();
try {
parser.parse(svgString, warningsAsErrors: true);
print('SVG is supported');
} catch (e) {
print('SVG contains unsupported features');
}
Copy the code
Note that the library currently only detects unsupported elements, such as the
Recommended Adobe Illustrator SVG configuration
To get the most out of Flutter_SVG in Adobe Illustrator, you need to follow specific recommendations.
-
-
- Styles: Choose to display properties rather than inline CSS, as CSS is not fully supported
- Images: Choose to embed rather than link to another file to get a single SVG that doesn’t depend on other files
- Object ID: Select the layer name to add a name for each layer of the SVG tag, or use the smallest layer name – the option is up to you
-
Render the SVG file in another canvas
Sometimes, you might want to render your SVG onto another canvas. SVGPicture helps you achieve this goal easily.
// example final String rawSvg = '''<svg viewBox="..." >... </svg>'''; final DrawableRoot svgRoot = await svg.fromSvgString(rawSvg, rawSvg); final Picture picture = svgRoot.toPicture(); svgRoot.scaleCanvasToViewBox(canvas); svgRoot.clipCanvasToViewBox(canvas); svgRoot.draw(canvas, size);Copy the code
conclusion
Using SVG files can be an important addition to your Flutter application, but SVG is not always the right answer to all your graphics problems. It is critical to observe your use cases and continuously measure the performance of your application and SVG, because you may need to replace SVG with another standard image format, such as PNG or JPEG.
Although Flutter does not support SVG, Dart’s native Flutter_SVG package has good performance and fast support for SVG files. The package is also relatively simple to use.
Keep in mind that the package is still under version 1.0.0, which may break the API changes. However, the authors do a good job of keeping the API as stable as possible. When using Flutter_SVG, make sure you always check the latest version of your package on pub.dev to stay up to date. Thanks for reading!
The postImplementing SVG in Flutter with flutter_svgappeared first onLogRocket Blog.