android - 如何在android map api V2中为标记设置动画?

标签 android google-maps android-mapview android-maps google-maps-android-api-2

我想实现平滑过渡以模拟汽车标记在 map 上的移动。

是否可以在 android map api v2 中为标记设置动画?

最佳答案

提供的版本都不适合我,因此我实现了我的自定义解决方案。它同时提供位置和旋转动画。

/**
 * 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;
} 

最后是 Google 的 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);
        }
    }
}

关于android - 如何在android map api V2中为标记设置动画?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13872803/

相关文章:

android - Cordova /一般 : Easiest way to develop for different screen layouts?

ios - 新的firebase框架将不允许谷歌地图用户授权显示

google-maps - Google maps api v3 显示静态图像而不是交互式 map

java - setInfoWindowAdapter 在 for() 循环中不刷新

android - 如何读取 build.gradle 中 local.properties 中定义的属性

android - 在 Android 上使用 aSmack 发送和接收图像

java - 我可以在 Android 谷歌地图 API 中设置折线不透明度吗

Android:在 MapView 上为 ItemizedOverlay 使用 9-patch 和文本

android - ScrollView 中的LinearLayout : Make last child have minHeight and fill empty space if necessary

android - 按下后应带来刷新的 Activity