Home > Net >  how to use SvgPicture.string as a imageProvider flutter
how to use SvgPicture.string as a imageProvider flutter

Time:12-04

im using flutter_svg package for svg. and now i want to use a svg inside a container as decoration like this,


Container(
  decoration: BoxDecoration(
    image: DecorationImage(
      image: SvgPicture.string(
                '''<svg viewBox="...">...</svg>'''
            ),
    ),
  ),
)

but the problem is DecorationImage peram expecting 'ImageProvider'. how can i do this ?

i tried flutter_svg_provider but its also not working. i found this solution, but dont know how to use.

CodePudding user response:

use a custom Decoration like this:

class SvgDecoration extends Decoration {
  SvgDecoration.string(String rawSvg, {this.key})
    : rawSvgFuture = Future.value(rawSvg);

  SvgDecoration.file(File file, {this.key})
    : rawSvgFuture = file.readAsString();

  SvgDecoration.asset(String asset, {this.key})
    : rawSvgFuture = rootBundle.loadString(asset);

  final Future<String> rawSvgFuture;
  final String? key;

  @override
  BoxPainter createBoxPainter([ui.VoidCallback? onChanged]) {
    return _SvgDecorationPainter(rawSvgFuture, onChanged, key);
  }
}

class _SvgDecorationPainter extends BoxPainter {
  _SvgDecorationPainter(this.rawSvgFuture, ui.VoidCallback? onChanged, String? key) {
    rawSvgFuture
      .then((rawSvg) => svg.fromSvgString(rawSvg, key ?? '(no key)'))
      .then((d) {
        drawable = d;
        onChanged?.call();
      });
  }

  final Future<String> rawSvgFuture;
  DrawableRoot? drawable;

  @override
  void paint(ui.Canvas canvas, ui.Offset offset, ImageConfiguration configuration) {
    if (drawable != null) {
      canvas
        ..save()
        ..translate(offset.dx, offset.dy);
      drawable!
        ..scaleCanvasToViewBox(canvas, configuration.size!)
        ..draw(canvas, offset & configuration.size!);
      canvas.restore();
    }
  }
}

as you can see there are 3 constructors: SvgDecoration.string, SvgDecoration.file and SvgDecoration.asset but of course you can add some other custom constructors (like SvgDecoration.network for example)

CodePudding user response:

The SvgPicture is a Widget, not an Image, which is why it can not be used as DecorationImage here. The way you can use the SvgPicture behind your Container is a Stack:

Stack(
  children: [
    SvgPicture.string(
      '''<svg viewBox="...">...</svg>''',
      (... width, height etc.)
    ),
    Container(
      child: (..., foreground widget)
    ),
  ],
)

Obviously, you have to make sure that both have the same size if you need it. But that depends on your usecase.

  • Related