【问题标题】:How do you use SVG's on Flutter Web?你如何在 Flutter Web 上使用 SVG?
【发布时间】:2019-12-02 02:49:15
【问题描述】:

flutter_web 文档说 dart:svg 已移植,但是如何将它与颤振资产/小部件系统一起使用?

【问题讨论】:

  • 我不知道如何使用 dart:svg 但我创建了一个示例项目,该项目使用 HtmlElementView 在移动设备和网络上显示 svg:github.com/masewo/flutter_svg_web_example
  • 谢谢 :) flutter_svg 这是一个选项,但它只适用于 android/iOS,websafe_svg 也适用于 web,但在 firefox 上无法正常工作。
  • websafe_svg 中的 Firefox 问题最近似乎已经修复,现在应该可以安全使用了。 github.com/peiffer-innovations/websafe_svg/issues/7

标签: flutter flutter-web


【解决方案1】:

老实说,我发现的最佳解决方案是通过网络为网络加载图像。将资产存储在某个 CDN 上,从 Web 版本的 CDN 获取它,然后在 iOS/Android 本地从您的资产中检索它。

我使用这个库创建了一个CrossPlatformSvg 小部件:https://pub.dev/packages/flutter_svg,类似于:

class CrossPlatformSvg {
  static Widget asset(
    String assetPath, {
    double width,
    double height,
    BoxFit fit = BoxFit.contain,
    Color color,
    alignment = Alignment.center,
    String semanticsLabel,
  }) {
    // `kIsWeb` is a special Flutter variable that just exists
    // Returns true if we're on web, false for mobile
    if (kIsWeb) {
      return Image.network(
        assetPath,
        width: width,
        height: height,
        fit: fit,
        color: color,
        alignment: alignment,
      );
    } else {
      return SvgPicture.network(
        assetPath,
        width: width,
        height: height,
        fit: fit,
        color: color,
        alignment: alignment,
        placeholderBuilder: (_) => Container(
          width: 30,
          height: 30,
          padding: EdgeInsets.all(30),
          child: CircularIndicator(),
        ),
      );
    }
  }
}

【讨论】:

  • 如果您将 svg 放在资产目录下并调用 Image.network,它甚至可以工作
  • 在调试模式下的网络上,我收到以下错误。所以我不认为 Image.network 支持 SVG。在 1.26.0-8.0.pre 上测试 • 通道开发 解析图像编解码器时引发以下 ImageCodecException:无法解码图像数据。
  • 似乎flutter放弃了svg支持,见github.com/flutter/flutter/issues/74489
【解决方案2】:

@aterenshkov 的方法对我有用(请参阅 Jack 的回答下的 cmets)。以下是要实施的细节...

iOS / Android

child: SvgPicture.asset('assets/yourimage.svg')

网络

// remove assets folder reference
child: SvgPicture.asset('yourimage.svg')

将这两个结合在一起......

import 'package:flutter/foundation.dart'; // provides kIsWeb property
...
child: kIsWeb ? SvgPicture.asset('yourimage.svg') : SvgPicture.asset('assets/yourimage.svg')

【讨论】:

    【解决方案3】:

    我的 Flutter Web 应用程序将使用 flutter_svg 在桌面 Web 浏览器而不是移动 Web 浏览器中呈现 SVG。我发现有必要使用 canvaskit 支持构建,以便 SVG 在移动设备上呈现:

    flutter build web --web-renderer canvaskit
    

    但是,docs 表示 canvaskit 增加了大约 2MB 的下载大小,这对我来说是个大问题。遗憾的是,在解决此问题之前,我将使用光栅图像。

    【讨论】:

      【解决方案4】:

      @RumbleFish 很好,但在许多地方使用三元运算会使代码变得混乱。

      我的做法是:

      • 在字符串上创建一个扩展函数以替换路径中的assets/
      extension ForWeb on String {
        String forWeb({required bool web}) => web ? this.replaceFirst('assets/','') : this;
      }
      
      • 现在在代码中:

      SvgPicture.asset("assets/images/logo.png".forWeb(web: kIsWeb));

      【讨论】:

        【解决方案5】:

        flutter_svg 1.0.0 版自 2021 年 12 月 2 日起推出,包括网络支持。因此,在 Flutter 项目中使用 svg 图像不再有障碍。

        【讨论】:

          猜你喜欢
          • 2020-11-07
          • 2021-04-15
          • 2020-03-12
          • 2023-01-25
          • 2020-01-28
          • 2021-07-01
          • 2020-11-24
          • 2022-01-02
          • 2019-09-17
          相关资源
          最近更新 更多