You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter中如何从网络SVG Sprite提取指定图标?

从SVG Sprite(Symbol集合)提取指定图标的Flutter实现方案

方法一:使用flutter_svg库

你可以通过解析SVG Sprite字符串,提取目标Symbol并构造成独立SVG来加载,步骤如下:

  1. 解析SVG Sprite文档,定位目标Symbol元素
  2. 将Symbol的内部内容包裹为完整的SVG结构
  3. 用flutter_svg加载该独立SVG

代码示例:

import 'package:flutter_svg/flutter_svg.dart';
import 'package:xml/xml.dart';

Future<SvgPicture> getIconFromSprite(String spriteSvg, String targetIconId) async {
  // 解析SVG Sprite字符串
  final xmlDoc = XmlDocument.parse(spriteSvg);
  // 查找指定ID的symbol元素
  final targetSymbol = xmlDoc.findAllElements('symbol').firstWhere(
    (elem) => elem.getAttribute('id') == targetIconId,
    orElse: () => throw ArgumentError("图标ID $targetIconId 不存在"),
  );
  // 获取symbol的viewBox属性(保证图标显示比例正确)
  final viewBox = targetSymbol.getAttribute('viewBox') ?? '0 0 24 24';
  // 构造可独立加载的SVG字符串
  final standaloneSvg = '''
<svg viewBox="$viewBox" xmlns="http://www.w3.org/2000/svg">
  ${targetSymbol.innerXml}
</svg>
''';
  // 返回可渲染的SvgPicture组件
  return SvgPicture.string(standaloneSvg);
}

// 使用示例
void loadTargetIcon() {
  String spriteFromNetwork = "你的网络SVG Sprite字符串";
  getIconFromSprite(spriteFromNetwork, "icon-without-shower").then((svgPic) {
    // 将svgPic加入Widget树渲染
  });
}

也可以直接用<use>标签引用Sprite中的Symbol,只需将Sprite内容和<use>标签放在同一SVG中:

String spriteSvg = "网络获取的Sprite字符串";
String useSvg = '''
<svg viewBox="0 0 30 30" xmlns="http://www.w3.org/2000/svg">
  $spriteSvg
  <use href="#icon-without-shower" />
</svg>
''';

// 加载渲染
SvgPicture.string(useSvg);

方法二:使用jovial_svg库

jovial_svg的处理逻辑类似,核心是提取目标Symbol并构造成独立SVG后加载:

import 'package:jovial_svg/jovial_svg.dart';
import 'package:xml/xml.dart';

Future<SvgImage> extractIcon(String spriteSvg, String iconId) async {
  final xmlDoc = XmlDocument.parse(spriteSvg);
  final targetSymbol = xmlDoc.findAllElements('symbol').firstWhere(
    (elem) => elem.getAttribute('id') == iconId,
    orElse: () => throw ArgumentError("图标ID $iconId 不存在"),
  );
  final viewBox = targetSymbol.getAttribute('viewBox') ?? '0 0 24 24';
  final standaloneSvg = '''
<svg viewBox="$viewBox" xmlns="http://www.w3.org/2000/svg">
  ${targetSymbol.innerXml}
</svg>
''';
  // 加载并解析SVG
  final loader = SvgLoader(standaloneSvg);
  return await loader.load();
}

// 使用示例
extractIcon(spriteFromNetwork, "icon-without-shower").then((svgImg) {
  // 用SvgPicture组件渲染
  SvgPicture(svgImage: svgImg);
});

备选方案:手动预处理

如果图标列表固定,你可以直接从SVG Sprite中复制目标<symbol>标签的内容,手动包裹成独立的SVG文件,放入项目资源目录后,用常规的资源加载方式调用即可。


内容的提问来源于stack exchange,提问作者Мартынов Олег

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 11:11:03