有没有办法在运行时更改 Google Maps Android API v2 标记的图标,而无需删除/重新添加我想更改其图标的标记?我可以对其应用变换(如旋转)吗?
谢谢。
有没有办法在运行时更改 Google Maps Android API v2 标记的图标,而无需删除/重新添加我想更改其图标的标记?我可以对其应用变换(如旋转)吗?
谢谢。
Google Play Services Rev 7
现在 更新到之后,我可以在运行时轻松更改标记图标
Marker.setIcon(BitmapDescriptor 图标)
是可用的,以前我确实删除并添加了标记来改变它的颜色。
目前您不能在运行时更改标记,也不能对其应用旋转。
不过,您可以使用一种解决方法 - 我正在研究 BlinkingMarker 类,我必须在运行时调整标记图像的不透明度。
目前唯一的解决方案是创建具有不同旋转的位图,然后定期添加/删除它们。这个解决方案的问题是添加/删除标记需要大量的内存分配,因此会导致不断的垃圾收集。更好、更流畅的解决方法是预先创建所有图像,然后一次将所有图像添加到地图中。之后,您可以使用该Marker.setVisible(boolean)
功能显示您当前需要的。
注意:在执行此操作之前测量您的位图,因为添加大量大位图可能会导致您的应用程序的内存大小变得非常大。
您可以在这里查看我的解决方法: https ://github.com/balazsbalazs/blinking-marker-mapsv2
这是闪烁的标记(更改位图的不透明度),但在同一行上,您可以应用任何类型的转换。
在2013 年9 月的 Google Maps Android API v2 版本中,现在有一种新setRotation()
的标记方法以及一种新setFlat()
方法。
以下是谷歌对新功能的描述:
给你的标记一个方向感
我们添加了一个标记旋转属性,允许您围绕它的锚点旋转标记。新的 flat 属性允许您使标记平放在地图表面上,而不是弹出以面对相机。这两个新属性对于在地图旋转或倾斜时指示指南针方向特别有用。
这是一篇描述新功能的文章。
文档在这个问题上非常清楚——
Icon A bitmap that's displayed in place of the default marker image. You can't change the icon once you've created the marker.
如果你想改变标记的外观,你有一些选择。正如您所注意到的,一种是删除标记并添加另一个标记。另一种是在同一位置放置多个标记,并在任何给定时间切换哪个标记可见。
我可以对其应用变换(如旋转)吗?
在使用图像创建标记之前,您可以对图像应用任何您喜欢的转换。
要在运行时更改选定的标记图标,只需添加
@Override
public boolean onMarkerClick(Marker marker) {
Marker.setIcon (BitmapDescriptor icon);
}
仅针对 Android 测试
为了在运行时更改标记的图标,我通过删除第 186 行中的“final”键将 icon 变量从final更改为non-final :
final BitmapDescriptor icon;
BitmapDescriptor icon;
并在第 136 行将 Marker Constructor 从“const”更改为“non-const”:
const Marker({
Marker({
要在包中进行更改,您必须遵循此说明。
使用 google_maps_flutter 存储库,您将收到类似“找不到 pubspec.yaml”的错误。那是因为 google_maps_flutter 包被放置在存储库的子目录中。
要获得正确的依赖项,您必须在 pubspec.yaml 中添加包的特定路径:
dependencies:
# google_maps_flutter: ^2.1.1
google_maps_flutter:
git:
url: https://github.com/[username]/plugins.git
path: packages/google_maps_flutter/google_maps_flutter/
然后,您可以通过直接将其设置在标记上来更改图标。我通过使用“OnTap”方法来做到这一点。
Marker marker = Marker(
icon: firstIcon,
markerId: MarkerId(id),
position: position,
infoWindow: InfoWindow(
title: name,
snippet: address,
),
onTap: () {
setState(() {
_markers[name]?.icon = secondIcon;
});
}
);
整个标记类:
@immutable
class Marker implements MapsObject {
/// Creates a set of marker configuration options.
///
/// Default marker options.
///
/// Specifies a marker that
/// * is fully opaque; [alpha] is 1.0
/// * uses icon bottom center to indicate map position; [anchor] is (0.5, 1.0)
/// * has default tap handling; [consumeTapEvents] is false
/// * is stationary; [draggable] is false
/// * is drawn against the screen, not the map; [flat] is false
/// * has a default icon; [icon] is `BitmapDescriptor.defaultMarker`
/// * anchors the info window at top center; [infoWindowAnchor] is (0.5, 0.0)
/// * has no info window text; [infoWindowText] is `InfoWindowText.noText`
/// * is positioned at 0, 0; [position] is `LatLng(0.0, 0.0)`
/// * has an axis-aligned icon; [rotation] is 0.0
/// * is visible; [visible] is true
/// * is placed at the base of the drawing order; [zIndex] is 0.0
/// * reports [onTap] events
/// * reports [onDragEnd] events
Marker({
required this.markerId,
this.alpha = 1.0,
this.anchor = const Offset(0.5, 1.0),
this.consumeTapEvents = false,
this.draggable = false,
this.flat = false,
this.icon = BitmapDescriptor.defaultMarker,
this.infoWindow = InfoWindow.noText,
this.position = const LatLng(0.0, 0.0),
this.rotation = 0.0,
this.visible = true,
this.zIndex = 0.0,
this.onTap,
this.onDrag,
this.onDragStart,
this.onDragEnd,
}) : assert(alpha == null || (0.0 <= alpha && alpha <= 1.0));
/// Uniquely identifies a [Marker].
final MarkerId markerId;
@override
MarkerId get mapsId => markerId;
/// The opacity of the marker, between 0.0 and 1.0 inclusive.
///
/// 0.0 means fully transparent, 1.0 means fully opaque.
final double alpha;
/// The icon image point that will be placed at the [position] of the marker.
///
/// The image point is specified in normalized coordinates: An anchor of
/// (0.0, 0.0) means the top left corner of the image. An anchor
/// of (1.0, 1.0) means the bottom right corner of the image.
final Offset anchor;
/// True if the marker icon consumes tap events. If not, the map will perform
/// default tap handling by centering the map on the marker and displaying its
/// info window.
final bool consumeTapEvents;
/// True if the marker is draggable by user touch events.
final bool draggable;
/// True if the marker is rendered flatly against the surface of the Earth, so
/// that it will rotate and tilt along with map camera movements.
final bool flat;
/// A description of the bitmap used to draw the marker icon.
BitmapDescriptor icon;
/// A Google Maps InfoWindow.
///
/// The window is displayed when the marker is tapped.
final InfoWindow infoWindow;
/// Geographical location of the marker.
final LatLng position;
/// Rotation of the marker image in degrees clockwise from the [anchor] point.
final double rotation;
/// True if the marker is visible.
final bool visible;
/// The z-index of the marker, used to determine relative drawing order of
/// map overlays.
///
/// Overlays are drawn in order of z-index, so that lower values means drawn
/// earlier, and thus appearing to be closer to the surface of the Earth.
final double zIndex;
/// Callbacks to receive tap events for markers placed on this map.
final VoidCallback? onTap;
/// Signature reporting the new [LatLng] at the start of a drag event.
final ValueChanged<LatLng>? onDragStart;
/// Signature reporting the new [LatLng] at the end of a drag event.
final ValueChanged<LatLng>? onDragEnd;
/// Signature reporting the new [LatLng] during the drag event.
final ValueChanged<LatLng>? onDrag;
/// Creates a new [Marker] object whose values are the same as this instance,
/// unless overwritten by the specified parameters.
Marker copyWith({
double? alphaParam,
Offset? anchorParam,
bool? consumeTapEventsParam,
bool? draggableParam,
bool? flatParam,
BitmapDescriptor? iconParam,
InfoWindow? infoWindowParam,
LatLng? positionParam,
double? rotationParam,
bool? visibleParam,
double? zIndexParam,
VoidCallback? onTapParam,
ValueChanged<LatLng>? onDragStartParam,
ValueChanged<LatLng>? onDragParam,
ValueChanged<LatLng>? onDragEndParam,
}) {
return Marker(
markerId: markerId,
alpha: alphaParam ?? alpha,
anchor: anchorParam ?? anchor,
consumeTapEvents: consumeTapEventsParam ?? consumeTapEvents,
draggable: draggableParam ?? draggable,
flat: flatParam ?? flat,
icon: iconParam ?? icon,
infoWindow: infoWindowParam ?? infoWindow,
position: positionParam ?? position,
rotation: rotationParam ?? rotation,
visible: visibleParam ?? visible,
zIndex: zIndexParam ?? zIndex,
onTap: onTapParam ?? onTap,
onDragStart: onDragStartParam ?? onDragStart,
onDrag: onDragParam ?? onDrag,
onDragEnd: onDragEndParam ?? onDragEnd,
);
}
/// Creates a new [Marker] object whose values are the same as this instance.
Marker clone() => copyWith();
/// Converts this object to something serializable in JSON.
Object toJson() {
final Map<String, Object> json = <String, Object>{};
void addIfPresent(String fieldName, Object? value) {
if (value != null) {
json[fieldName] = value;
}
}
addIfPresent('markerId', markerId.value);
addIfPresent('alpha', alpha);
addIfPresent('anchor', _offsetToJson(anchor));
addIfPresent('consumeTapEvents', consumeTapEvents);
addIfPresent('draggable', draggable);
addIfPresent('flat', flat);
addIfPresent('icon', icon.toJson());
addIfPresent('infoWindow', infoWindow._toJson());
addIfPresent('position', position.toJson());
addIfPresent('rotation', rotation);
addIfPresent('visible', visible);
addIfPresent('zIndex', zIndex);
return json;
}
@override
bool operator ==(Object other) {
if (identical(this, other)) return true;
if (other.runtimeType != runtimeType) return false;
final Marker typedOther = other as Marker;
return markerId == typedOther.markerId &&
alpha == typedOther.alpha &&
anchor == typedOther.anchor &&
consumeTapEvents == typedOther.consumeTapEvents &&
draggable == typedOther.draggable &&
flat == typedOther.flat &&
icon == typedOther.icon &&
infoWindow == typedOther.infoWindow &&
position == typedOther.position &&
rotation == typedOther.rotation &&
visible == typedOther.visible &&
zIndex == typedOther.zIndex;
}
@override
int get hashCode => markerId.hashCode;
@override
String toString() {
return 'Marker{markerId: $markerId, alpha: $alpha, anchor: $anchor, '
'consumeTapEvents: $consumeTapEvents, draggable: $draggable, flat: $flat, '
'icon: $icon, infoWindow: $infoWindow, position: $position, rotation: $rotation, '
'visible: $visible, zIndex: $zIndex, onTap: $onTap, onDragStart: $onDragStart, '
'onDrag: $onDrag, onDragEnd: $onDragEnd}';
}
}