如何在 google_maps_flutter Flutter 插件中使用 SVG 标记?
How to use SVG markers in google_maps_flutter Flutter plugin?
我希望使用 .svg 图像作为图标放置标记。我正在使用 google_maps_flutter 库。这适用于 .png 转换后的图像,但我没有找到直接使用 .svg 文件的方法。
看完这个问题我在这里发帖:
并尝试使用此线程中描述的 fromAssetImage 方法:
我希望这个新版本的库能帮助解决我的问题。
我尝试用下面的代码解决它:
MapWidget class
for (Place place in widget.places) {
place.toMarker(
context,
() => _onPlaceTapped(place),
).then(setState((){
markerSet.add
}));
}
放置class
Future<Marker> toMarker(BuildContext context, VoidCallback onTap) async {
return Marker(
markerId: MarkerId(id.toString()),
position: LatLng(lat, lon),
icon: await category.markerIcon(createLocalImageConfiguration(context)),
onTap: onTap,
);
类别class
Future<BitmapDescriptor> markerIcon(ImageConfiguration configuration) async {
BitmapDescriptor b;
switch (type) {
case CategoryType.FirstCategory:
b = await BitmapDescriptor.fromAssetImage(configuration, 'assets/markers/marker-first.svg');
break;
case CategoryType.SecondCategory:
b = await BitmapDescriptor.fromAssetImage(configuration, 'assets/markers/marker-second.svg');
break;
default:
b = await BitmapDescriptor.fromAssetImage(configuration, 'assets/markers/marker-third.svg');
break;
}
return b;
}
如果您想知道,图像的路径已添加到 pubspec.yaml。
我希望地图上默认的红色 google 标记被一些自定义标记替换(每个自定义标记上应该有一个小图标图像),但是只显示默认标记(不是默认标记)在 switch 语句中,我说的是 google 的默认标记)。
使用iOS模拟器和google_maps_flutter0.5.15+1库版本没有错误信息。
您可以在这里找到这个问题的答案:
我尝试了 rednuht 的回答,效果非常好。
编辑(回顾)
答案需要使用 flutter_svg 插件(^0.13 或 0.14.1 似乎适合我自己)。
首先,创建一个函数,该函数将从资产中为您提供 BitmapDescriptor。确保资产已在您的 pubspec 文件中声明。
import 'dart:ui' as ui;
import 'package:flutter/services.dart';
import 'package:flutter_svg/flutter_svg.dart';
Future<BitmapDescriptor> _bitmapDescriptorFromSvgAsset(BuildContext context, String assetName) async {
String svgString = await DefaultAssetBundle.of(context).loadString(assetName);
//Draws string representation of svg to DrawableRoot
DrawableRoot svgDrawableRoot = await svg.fromSvgString(svgString, null);
ui.Picture picture = svgDrawableRoot.toPicture();
ui.Image image = await picture.toImage(26, 37);
ByteData bytes = await image.toByteData(format: ui.ImageByteFormat.png);
return BitmapDescriptor.fromBytes(bytes.buffer.asUint8List());
}
我在我的应用程序开始时实例化了一个 Map 对象,这样我就可以在不使用大量 async/await 调用的情况下使用 BitmapDescriptors。
data_model.dart
Map<CategoryType, BitmapDescriptor> descriptors = Map<Category, BitmapDescriptor>();
Future<void> loadBitmapDescriptors(context) async {
descriptors[CategoryType.FirstCatgory] = await _bitmapDescriptorFromSvgAsset(context, 'assets/markers/marker-first.svg');
descriptors[CategoryType.SecondCategory] = await _bitmapDescriptorFromSvgAsset(context, 'assets/markers/marker-second.svg');
descriptors[CategoryType.ThirdCategory] = await _bitmapDescriptorFromSvgAsset(context, 'assets/markers/marker-third.svg');
}
main.dart
DataModel.of(context).loadBitmapDescriptors(context);
所以在那之后我要做的就是在需要时正确调用它。
Marker marker = Marker(markerId: MarkerId(id.toString()), icon: descriptors[category], position: LatLng(lat, lon));
我遇到了同样的问题,由于没有 de devicePixelRatio 它显示了像素化标记,所以这个实现结束了。
Future<BitmapDescriptor> getBitmapDescriptorFromSVGAsset(
BuildContext context,
String svgAssetLink, {
Size size = const Size(30, 30),
}) async {
String svgString = await DefaultAssetBundle.of(context).loadString(
svgAssetLink,
);
final drawableRoot = await svg.fromSvgString(
svgString,
'debug: $svgAssetLink',
);
final ratio = ui.window.devicePixelRatio.ceil();
final width = size.width.ceil() * ratio;
final height = size.height.ceil() * ratio;
final picture = drawableRoot.toPicture(
size: Size(
width.toDouble(),
height.toDouble(),
),
);
final image = await picture.toImage(width, height);
final byteData = await image.toByteData(format: ui.ImageByteFormat.png);
final uInt8List = byteData.buffer.asUint8List();
return BitmapDescriptor.fromBytes(uInt8List);
}
我希望使用 .svg 图像作为图标放置标记。我正在使用 google_maps_flutter 库。这适用于 .png 转换后的图像,但我没有找到直接使用 .svg 文件的方法。
看完这个问题我在这里发帖:
并尝试使用此线程中描述的 fromAssetImage 方法:
我希望这个新版本的库能帮助解决我的问题。
我尝试用下面的代码解决它:
MapWidget class
for (Place place in widget.places) {
place.toMarker(
context,
() => _onPlaceTapped(place),
).then(setState((){
markerSet.add
}));
}
放置class
Future<Marker> toMarker(BuildContext context, VoidCallback onTap) async {
return Marker(
markerId: MarkerId(id.toString()),
position: LatLng(lat, lon),
icon: await category.markerIcon(createLocalImageConfiguration(context)),
onTap: onTap,
);
类别class
Future<BitmapDescriptor> markerIcon(ImageConfiguration configuration) async {
BitmapDescriptor b;
switch (type) {
case CategoryType.FirstCategory:
b = await BitmapDescriptor.fromAssetImage(configuration, 'assets/markers/marker-first.svg');
break;
case CategoryType.SecondCategory:
b = await BitmapDescriptor.fromAssetImage(configuration, 'assets/markers/marker-second.svg');
break;
default:
b = await BitmapDescriptor.fromAssetImage(configuration, 'assets/markers/marker-third.svg');
break;
}
return b;
}
如果您想知道,图像的路径已添加到 pubspec.yaml。
我希望地图上默认的红色 google 标记被一些自定义标记替换(每个自定义标记上应该有一个小图标图像),但是只显示默认标记(不是默认标记)在 switch 语句中,我说的是 google 的默认标记)。
使用iOS模拟器和google_maps_flutter0.5.15+1库版本没有错误信息。
您可以在这里找到这个问题的答案:
我尝试了 rednuht 的回答,效果非常好。
编辑(回顾)
答案需要使用 flutter_svg 插件(^0.13 或 0.14.1 似乎适合我自己)。
首先,创建一个函数,该函数将从资产中为您提供 BitmapDescriptor。确保资产已在您的 pubspec 文件中声明。
import 'dart:ui' as ui;
import 'package:flutter/services.dart';
import 'package:flutter_svg/flutter_svg.dart';
Future<BitmapDescriptor> _bitmapDescriptorFromSvgAsset(BuildContext context, String assetName) async {
String svgString = await DefaultAssetBundle.of(context).loadString(assetName);
//Draws string representation of svg to DrawableRoot
DrawableRoot svgDrawableRoot = await svg.fromSvgString(svgString, null);
ui.Picture picture = svgDrawableRoot.toPicture();
ui.Image image = await picture.toImage(26, 37);
ByteData bytes = await image.toByteData(format: ui.ImageByteFormat.png);
return BitmapDescriptor.fromBytes(bytes.buffer.asUint8List());
}
我在我的应用程序开始时实例化了一个 Map 对象,这样我就可以在不使用大量 async/await 调用的情况下使用 BitmapDescriptors。
data_model.dart
Map<CategoryType, BitmapDescriptor> descriptors = Map<Category, BitmapDescriptor>();
Future<void> loadBitmapDescriptors(context) async {
descriptors[CategoryType.FirstCatgory] = await _bitmapDescriptorFromSvgAsset(context, 'assets/markers/marker-first.svg');
descriptors[CategoryType.SecondCategory] = await _bitmapDescriptorFromSvgAsset(context, 'assets/markers/marker-second.svg');
descriptors[CategoryType.ThirdCategory] = await _bitmapDescriptorFromSvgAsset(context, 'assets/markers/marker-third.svg');
}
main.dart
DataModel.of(context).loadBitmapDescriptors(context);
所以在那之后我要做的就是在需要时正确调用它。
Marker marker = Marker(markerId: MarkerId(id.toString()), icon: descriptors[category], position: LatLng(lat, lon));
我遇到了同样的问题,由于没有 de devicePixelRatio 它显示了像素化标记,所以这个实现结束了。
Future<BitmapDescriptor> getBitmapDescriptorFromSVGAsset(
BuildContext context,
String svgAssetLink, {
Size size = const Size(30, 30),
}) async {
String svgString = await DefaultAssetBundle.of(context).loadString(
svgAssetLink,
);
final drawableRoot = await svg.fromSvgString(
svgString,
'debug: $svgAssetLink',
);
final ratio = ui.window.devicePixelRatio.ceil();
final width = size.width.ceil() * ratio;
final height = size.height.ceil() * ratio;
final picture = drawableRoot.toPicture(
size: Size(
width.toDouble(),
height.toDouble(),
),
);
final image = await picture.toImage(width, height);
final byteData = await image.toByteData(format: ui.ImageByteFormat.png);
final uInt8List = byteData.buffer.asUint8List();
return BitmapDescriptor.fromBytes(uInt8List);
}