Implementing SVG in Flutter with flutter_svg

Scalable Vector Graphics (SVG) is one of the most widely used file image formats in applications. Because it offers several advantages over bitmap files, especially when it comes to retaining image quality while scaling, it’s difficult to start building a Flutter application without first considering using SVG.

In this article, you’ll learn how and when to use SVG files in a Flutter application.

Using SVG in Flutter

Skia, a 2D graphics library and core component of Flutter, can only serialize images into SVG files. Thus, decoding or rendering SVG images with Skia is not possible. Fortunately, the community comes to the rescue with a fantastic Dart-native package called flutter_svg that renders and decodes SVG quickly.

What is flutter_svg?

The flutter_svg package has implemented a picture cache that stores a ui:Picture class. This is the SkPicture wrapper of 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 repeatedly parsing XML files. Let’s take a look at the SvgPicture.asset constructor:

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);

By looking at the implementation, you’ll notice that the stream notifications from pictureProvider update the picture of SvgPicture.

 void _resolveImage() {
final PictureStream newStream = widget.pictureProvider
.resolve(createLocalPictureConfiguration(context));
assert(newStream != null); // ignore: unnecessary_null_comparison
_updateSourceStream(newStream);
}

In this code block, the stream from the pictureProvider is populated with ui.Picture by a completer of the picture 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;
}

Adding the flutter_svg plugin

To add this package to your Flutter dependencies, you can run:

flutter pub add flutter_svg

Alternatively, you can add flutter_svg to your pubspec.yaml file:

dependencies:
  flutter_svg: ^0.22.0

Make sure that you run flutter pub get either in your terminal or using your editor. Once installation is complete, import the package in your Dart code where you want to use this package:

import 'package:flutter_svg/flutter_svg.dart';

Using flutter_svg in your Flutter app

There are several ways to use this package, but we’ll cover the most common use cases.

One option is to load an 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,
);

You can also load an SVG file from an URL, like so:

// example
final Widget networkSvg = SvgPicture.network(
  'https://site-that-takes-a-while.com/image.svg',
);

Finally, you can load an SVG from an SVG code:

// example
SvgPicture.string(
  '''<svg viewBox="...">...</svg>'''
);

Extending SVG functionalities in Flutter

Once you have your SVG file loaded, the first step is to change the color or tint of the image:

// example
final String assetName = 'assets/up_arrow.svg';
final Widget svgIcon = SvgPicture.asset(
  assetName,
  color: Colors.red,
);

Using a semantics label helps to describe the purpose of the image and enhances accessibility. To achieve this, you can add the semanticsLabel parameter. The semantic label will not be shown in the UI.

// example
final String assetName = 'assets/up_arrow.svg';
final Widget svgIcon = SvgPicture.asset(
  assetName,
  color: Colors.red,
  semanticsLabel: 'A red up arrow'
);

The flutter_svg package renders an empty box, LimitedBox, as the default placeholder if there are no height or width assignments on the SvgPicture. However, if a height or width is specified on the SvgPicture, a SizedBox will be rendered to ensure a better layout experience.

The placeholder can be replaced, though, which is great for improving the user experience, especially when loading assets via a network request where there may be a delay.

// 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(30.0),
      child: const CircularProgressIndicator()),
);

In this example, I’ve chosen CircularProgressIndicator to display a progress indicator while the image is loading. You may add any other widget that you wish. For example, you might use a custom loading widget to replace CircularProgressIndicator.

Checking SVG compatibility with flutter_svg

You should know that the flutter_svg library does not support all SVG features. The package does, however, provide a helper method to ensure that 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');
}

Please note that the library currently only detects unsupported elements like the <style> tag, but does not recognize unsupported attributes.

Recommended Adobe Illustrator SVG configuration

To use make the most use of flutter_svg with Adobe Illustrator, you need to follow specific recommendations:

      • Styling: choose presentation attributes instead of inline CSS because CSS is not fully supported
      • Images: choose to embed, not link, to another file to get a single SVG with no dependency on other files
      • Objects IDs: choose layer names in order to add a name to every layer for SVG tags, or use minimal layer names — the choice is yours!

SVG flutter image options

Rendering SVG files in another canvas

There may be times where you’d like to render your SVG into another canvas. SVGPicture helps you easily achieve this:

// 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);

Conclusion

Using SVG files can be a great addition to your Flutter app, but SVG isn’t always the right answer to all of your image problems. It’s crucial to observe your use cases and measure your app and SVG performance continuously, as you might need to replace SVG with another standard image format, such as PNG or JPEG.

Although Flutter doesn’t support SVG natively, the Dart-native flutter_svg package has excellent performant and fast support for SVG files. The package is relatively simple to use, too.

Keep in mind that the package version is still below 1.0.0, which can break changes in API. However, the author has done a great job of keeping the API as stable as possible. When using flutter_svg, make sure you always check the last version of the package on pub.dev to stay up to date. Thanks for reading!

The post Implementing SVG in Flutter with flutter_svg appeared first on LogRocket Blog.

This article was republished from its original source.
Call Us: 1(800)730-2416

Pixeldust is a 20-year-old web development agency specializing in Drupal and WordPress and working with clients all over the country. With our best in class capabilities, we work with small businesses and fortune 500 companies alike. Give us a call at 1(800)730-2416 and let’s talk about your project.

FREE Drupal SEO Audit

Test your site below to see which issues need to be fixed. We will fix them and optimize your Drupal site 100% for Google and Bing. (Allow 30-60 seconds to gather data.)

Powered by

Implementing SVG in Flutter with flutter_svg

On-Site Drupal SEO Master Setup

We make sure your site is 100% optimized (and stays that way) for the best SEO results.

With Pixeldust On-site (or On-page) SEO we make changes to your site’s structure and performance to make it easier for search engines to see and understand your site’s content. Search engines use algorithms to rank sites by degrees of relevance. Our on-site optimization ensures your site is configured to provide information in a way that meets Google and Bing standards for optimal indexing.

This service includes:

  • Pathauto install and configuration for SEO-friendly URLs.
  • Meta Tags install and configuration with dynamic tokens for meta titles and descriptions for all content types.
  • Install and fix all issues on the SEO checklist module.
  • Install and configure XML sitemap module and submit sitemaps.
  • Install and configure Google Analytics Module.
  • Install and configure Yoast.
  • Install and configure the Advanced Aggregation module to improve performance by minifying and merging CSS and JS.
  • Install and configure Schema.org Metatag.
  • Configure robots.txt.
  • Google Search Console setup snd configuration.
  • Find & Fix H1 tags.
  • Find and fix duplicate/missing meta descriptions.
  • Find and fix duplicate title tags.
  • Improve title, meta tags, and site descriptions.
  • Optimize images for better search engine optimization. Automate where possible.
  • Find and fix the missing alt and title tag for all images. Automate where possible.
  • The project takes 1 week to complete.