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.