如何在Flutter Web上使用SVG?

时间:2019-07-24 02:59:56

标签: flutter-web

flutter_web docos对dart:svg进行了移植,但是如何在flutter资产/小部件系统中使用它?

4 个答案:

答案 0 :(得分:5)

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

我使用以下库创建了一个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(), ), ); } } } 小部件:https://pub.dev/packages/flutter_svg,类似于:

import Vapor
import FluentPostgreSQL

final class WorkWithPostgres {
    
    private let databaseConfig = PostgreSQLDatabaseConfig(hostname: "localhost", port: 5432, username: "RutrackerTech", database: "vaporpostgres", password: "ru628trac4er")
    
    let postgres: PostgreSQLDatabase
    
    static let shared = WorkWithPostgres()
    
    private init() {
        postgres = PostgreSQLDatabase(config: databaseConfig)
    }
    
    /// Will it create undeleted memory leaks?
    func shutdownGracefully(worker: MultiThreadedEventLoopGroup, completion: (() -> Void)?) {
        worker.shutdownGracefully { error in
            completion?()
        }
    }
    
    /// Will it create udeleted memory leaks?
    func connect(completion: ((MultiThreadedEventLoopGroup, PostgreSQLConnection) -> Void)?) {
        let worker = MultiThreadedEventLoopGroup(numberOfThreads: 1)
        let eventLoopFuturePostgreSQLConnection = postgres.newConnection(on: worker)
        let _ = eventLoopFuturePostgreSQLConnection.map { postgreSQLConnection in
            completion?(worker, postgreSQLConnection)
        }
    }
    
    func readAll<T: PostgreSQLModel>(postgreSQLModel: T.Type, completion: (([T]) -> Void)?) {
        connect { worker, connection in
            let _ = postgreSQLModel.query(on: connection).all().map { databaseData in
                self.shutdownGracefully(worker: worker) {
                    completion?(databaseData)
                }
            }
        }
    }
    
    func create<T: PostgreSQLModel>(postgreSQLModel: T) {
        connect { worker, connection in
            let _ = postgreSQLModel.save(on: connection).whenComplete {
                self.shutdownGracefully(worker: worker, completion: nil)
            }
        }
    }
    
}

答案 1 :(得分:2)

@aterenshkov 的方法对我有用(请参阅 Jack 回答下的评论)。以下是实施的详细信息...

iOS/安卓

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

答案 2 :(得分:2)

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

flutter build web --web-renderer canvaskit

然而,docs 声明 canvaskit 增加了大约 2MB 的下载大小,这对我来说是个大问题。遗憾地讲,但我将使用光栅图像,直到这个解决。

答案 3 :(得分:0)

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