回答
尝试使用下面的代码在Google地图V2上对标记进行动画制作。 您需要使用Interpolator
类应用动画上的标记和处理它的处理器为动画如下:
public void animateMarker(final Marker marker, final LatLng toPosition, final boolean hideMarker) { final Handler handler = new Handler(); final long start = SystemClock.uptimeMillis(); Projection proj = mGoogleMapObject.getProjection(); Point startPoint = proj.toScreenLocation(marker.getPosition()); final LatLng startLatLng = proj.fromScreenLocation(startPoint); final long duration = 500; final Interpolator interpolator = new LinearInterpolator(); handler.post(new Runnable() { @Override public void run() { long elapsed = SystemClock.uptimeMillis() - start; float t = interpolator.getInterpolation((float) elapsed /duration); double lng = t * toPosition.longitude + (1 - t) * startLatLng.longitude; double lat = t * toPosition.latitude + (1 - t) * startLatLng.latitude; marker.setPosition(new LatLng(lat, lng)); if (t < 1.0) { // Post again 16ms later. handler.postDelayed(this, 16); } else { if (hideMarker) { marker.setVisible(false); } else { marker.setVisible(true); } } } }); }
非常感谢。这非常有帮助。 – Anil
你究竟如何实现这个代码? @阿尼尔?你可以让标记沿着gps坐标移动吗?请张贴答案。 – momokjaaaaa
嘿,非常感谢。有用。但标记在开始标记动画之前来回移动。你能告诉我如何解决它。 – Sadia
只是实现了一个版本,试试这个
public class MarkerAnimation {
static GoogleMap map;
ArrayList<LatLng> _trips = new ArrayList<>() ;
Marker _marker;
LatLngInterpolator _latLngInterpolator = new LatLngInterpolator.Spherical();
public void animateLine(ArrayList<LatLng> Trips,GoogleMap map,Marker marker,Context current){
_trips.addAll(Trips);
_marker = marker;
animateMarker();
}
public void animateMarker() {
TypeEvaluator<LatLng> typeEvaluator = new TypeEvaluator<LatLng>() {
@Override
public LatLng evaluate(float fraction, LatLng startValue, LatLng endValue) {
return _latLngInterpolator.interpolate(fraction, startValue, endValue);
}
};
Property<Marker, LatLng> property = Property.of(Marker.class, LatLng.class, "position");
ObjectAnimator animator = ObjectAnimator.ofObject(_marker, property, typeEvaluator, _trips.get(0));
//ObjectAnimator animator = ObjectAnimator.o(view, "alpha", 0.0f);
animator.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationCancel(Animator animation) {
// animDrawable.stop();
}
@Override
public void onAnimationRepeat(Animator animation) {
// animDrawable.stop();
}
@Override
public void onAnimationStart(Animator animation) {
// animDrawable.stop();
}
@Override
public void onAnimationEnd(Animator animation) {
// animDrawable.stop();
if (_trips.size() > 1) {
_trips.remove(0);
animateMarker();
}
}
});
animator.setDuration(300);
animator.start();
}
LatLngInterpolator类由Google预先编写,您可以使用如下:
public interface LatLngInterpolator {
public LatLng interpolate(float fraction, LatLng a, LatLng b);
public class Spherical implements LatLngInterpolator {
@Override
public LatLng interpolate(float fraction, LatLng from, LatLng to) {
// http://en.wikipedia.org/wiki/Slerp
double fromLat = toRadians(from.latitude);
double fromLng = toRadians(from.longitude);
double toLat = toRadians(to.latitude);
double toLng = toRadians(to.longitude);
double cosFromLat = cos(fromLat);
double cosToLat = cos(toLat);
// Computes Spherical interpolation coefficients.
double angle = computeAngleBetween(fromLat, fromLng, toLat, toLng);
double sinAngle = sin(angle);
if (sinAngle < 1E-6) {
return from;
}
double a = sin((1 - fraction) * angle)/sinAngle;
double b = sin(fraction * angle)/sinAngle;
// Converts from polar to vector and interpolate.
double x = a * cosFromLat * cos(fromLng) + b * cosToLat * cos(toLng);
double y = a * cosFromLat * sin(fromLng) + b * cosToLat * sin(toLng);
double z = a * sin(fromLat) + b * sin(toLat);
// Converts interpolated vector back to polar.
double lat = atan2(z, sqrt(x * x + y * y));
double lng = atan2(y, x);
return new LatLng(toDegrees(lat), toDegrees(lng));
}
private double computeAngleBetween(double fromLat, double fromLng, double toLat, double toLng) {
// Haversine's formula
double dLat = fromLat - toLat;
double dLng = fromLng - toLng;
return 2 * asin(sqrt(pow(sin(dLat/2), 2) +
cos(fromLat) * cos(toLat) * pow(sin(dLng/2), 2)));
}
}
}
然后实例的MarkerAnimation类的一个对象,并调用这样的方法:提供版本的
MarkerAnimation.animateLine(TripPoints,map,MovingMarker,context);
没有为我工作,所以我实现了我的自定义解决方案。它提供了位置和旋转动画。
/**
* Method to animate marker to destination location
* @param destination destination location (must contain bearing attribute, to ensure
* marker rotation will work correctly)
* @param marker marker to be animated
*/
public static void animateMarker(Location destination, Marker marker) {
if (marker != null) {
LatLng startPosition = marker.getPosition();
LatLng endPosition = new LatLng(destination.getLatitude(), destination.getLongitude());
float startRotation = marker.getRotation();
LatLngInterpolator latLngInterpolator = new LatLngInterpolator.LinearFixed();
ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, 1);
valueAnimator.setDuration(1000); // duration 1 second
valueAnimator.setInterpolator(new LinearInterpolator());
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override public void onAnimationUpdate(ValueAnimator animation) {
try {
float v = animation.getAnimatedFraction();
LatLng newPosition = latLngInterpolator.interpolate(v, startPosition, endPosition);
marker.setPosition(newPosition);
marker.setRotation(computeRotation(v, startRotation, destination.getBearing()));
} catch (Exception ex) {
// I don't care atm..
}
}
});
valueAnimator.start();
}
}
动画指定部分的旋转计算。标记是在更接近,从开始到结束的旋转方向旋转:
private static float computeRotation(float fraction, float start, float end) {
float normalizeEnd = end - start; // rotate start to 0
float normalizedEndAbs = (normalizeEnd + 360) % 360;
float direction = (normalizedEndAbs > 180) ? -1 : 1; // -1 = anticlockwise, 1 = clockwise
float rotation;
if (direction > 0) {
rotation = normalizedEndAbs;
} else {
rotation = normalizedEndAbs - 360;
}
float result = fraction * rotation + start;
return (result + 360) % 360;
}
最后谷歌的LatLngInterpolator
:
private interface LatLngInterpolator {
LatLng interpolate(float fraction, LatLng a, LatLng b);
class LinearFixed implements LatLngInterpolator {
@Override
public LatLng interpolate(float fraction, LatLng a, LatLng b) {
double lat = (b.latitude - a.latitude) * fraction + a.latitude;
double lngDelta = b.longitude - a.longitude;
// Take the shortest path across the 180th meridian.
if (Math.abs(lngDelta) > 180) {
lngDelta -= Math.signum(lngDelta) * 360;
}
double lng = lngDelta * fraction + a.longitude;
return new LatLng(lat, lng);
}
}
}
我正在尝试实现这个如何添加轴承到目的地吗?,你有最终的项目github上的任何来源? –
@FrankOdoom您应该通过'setBearing(float)'或'bearingTo(Location)'方法在传递'Location destination'参数上正确设置方位。 – skywall
这是我找到的最佳答案。根本没有闪烁。 –
- 1. Android:如何在google map API中将imageView设置为标记android?
- 2. Android Maps v2 - 动画标记
- 3. Android Map v2标记泡泡
- 4. Android Google Maps v2:设置动画标记大小
- 5. 在Google地图v2上设置动画标记
- 6. 如何在google map api v3中逐一设置标记?
- 7. 如何启用单点触摸后拖动标记(Android Map Api v2)?
- 8. Android - Google map api v2&android 2.3.7
- 9. 在当前位置设置自定义标记图标 - Android API v2
- 10. Android,如何从Google Map V2中删除所有标记?
- 11. 如何在Google Map API v2的MapFragment上显示多个标记?
- 12. 从android map map api v2中的KML文件中渲染CDATA HTML标记
- 13. android map v2标记onclick不会缩放
- 14. google map api v2 android-java.lang.NullPointerException
- 15. Android Google Map Api V2 OnCameraChangeListener
- 16. 隐藏infowindow android map api v2
- 17. Google Map API v2 - GeoCoder - 如何自定义标记?
- 18. Map is not loading Map api v2
- 19. 如何在Android中显示Google Map v2
- 20. Android Google地图API V2中心标记
- 21. Google Map v2 android
- 22. 在Android中将标记倒置Google地图API V2
- 23. 在Android Google Maps API v2中标记用户位置
- 24. Android - 自动更新标记位置Google地图api v2
- 25. 对于Android谷歌地图API V2你如何设置标记的zindex?
- 26. 如何限制Android Google Maps API v2中的标记数量?
- 27. Android Google Map v2 - 点击标记infoWindow时开始活动
- 28. 在Android Map v2 API中如何让屏幕图像分享?
- 29. Google Map API:如何在AS3中动态标记中心?
- 30. Google Maps API v2街景标记图标
据我了解,你需要原生地图API V2行为从一个位置移动标记到另一个顺利? –
你可能会看到这篇文章http://stackoverflow.com/questions/13728041/move-markers-in-google-map-v2-android –
可能的重复[如何将动画标记添加到Android地图上? ](http://stackoverflow.com/questions/8191582/how-to-animate-marker-when-it-is-added-to-map-on-android) – bummi