在Google地图v2中为标记的旋转设置动画

use*_*760 4 android google-maps google-maps-markers android-animation

我正在使用谷歌地图v2.我在地图上有一个标记,这个标记每次都会改变旋转.我想动画制作者的旋转以平滑旋转.任何人都可以帮忙

use*_*007 6

这是我的实现平滑标记运动与制造商图像旋转(当它设置为FLAT [重要]).标记平滑地移动到请求的位置,并且以适当的方向旋转到所需的程度.例如,当从5deg移动到355deg时,它逆时针移动,当355deg移动到5deg时,它顺时针移动.

public void animateMarker(final Location location)
{
    if (myMarkerLOC != null) {
        final LatLngInterpolator latLngInterpolator = new LatLngInterpolator.LinearFixed();
        ValueAnimator valueAnimator = new ValueAnimator();
        final LatLng startPosition = myMarkerLOC.getPosition();
        final float startRotation = myMarkerLOC.getRotation();
        final float angle = 180 - Math.abs(Math.abs(startRotation - location.getBearing()) - 180);
        final float right = WhichWayToTurn(startRotation, location.getBearing());
        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener()
        {
            @Override
            public void onAnimationUpdate(ValueAnimator animation)
            {
                try {
                    if (myMarkerLOC == null) // oops... destroying map during animation...
                    {
                        return;
                    }
                    float v = animation.getAnimatedFraction();
                    LatLng newPosition = latLngInterpolator.interpolate(v, startPosition, PositionUtil.toLatLng(location));
                    float rotation = startRotation + right * v * angle;
                    myMarkerLOC.setRotation((float) rotation);
                    myMarkerLOC.setPosition(newPosition);
                } catch (Exception ex) {
                    // I don't care atm..
                }
            }
        });
        valueAnimator.setFloatValues(0, 1);
        valueAnimator.setDuration(300);
        valueAnimator.start();
    }
}
private float WhichWayToTurn(float currentDirection, float targetDirection)
{
    float diff = targetDirection - currentDirection;
    if (Math.abs(diff) == 0)
    {
        return 0;
    }
    if(diff > 180)
    {
        return -1;
    }
    else
    {
        return 1;
    }
}
public interface LatLngInterpolator 
{
    public LatLng interpolate(float fraction, LatLng a, LatLng b);

    public class Linear implements LatLngInterpolator 
    {
        @Override
        public LatLng interpolate(float fraction, LatLng a, LatLng b) 
        {
            double lat = (b.latitude - a.latitude) * fraction + a.latitude;
            double lng = (b.longitude - a.longitude) * fraction + a.longitude;
            return new LatLng(lat, lng);
        }
    }
    public 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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

缺少"toLatLong"方法的实现:

 public static LatLng toLatLng(final Location location)
 {
    return new LatLng(location.getLatitude(), location.getLongitude());
 }
Run Code Online (Sandbox Code Playgroud)

我希望有所帮助.


Bha*_*cer 5

boolean isRotating = false;
public void rotateMarker(final Marker marker, final float toRotation) {
    if(!isRotating) {
        isRotating = true;
        final Handler handler = new Handler();
        final long start = SystemClock.uptimeMillis();
        final float startRotation = marker.getRotation();
        final long duration = 1000;
        float deltaRotation = Math.abs(toRotation - startRotation) % 360;
        final float rotation = (deltaRotation > 180 ? 360 - deltaRotation : deltaRotation) *
                ((toRotation - startRotation >= 0 && toRotation - startRotation <= 180) || (toRotation - startRotation <= -180 && toRotation - startRotation >= -360) ? 1 : -1);

        final LinearInterpolator interpolator = new LinearInterpolator();
        handler.post(new Runnable() {
            @Override
            public void run() {
                long elapsed = SystemClock.uptimeMillis() - start;
                float t = interpolator.getInterpolation((float) elapsed / duration);
                marker.setRotation((startRotation + t * rotation) % 360);
                if (t < 1.0) {
                    // Post again 16ms later.
                    handler.postDelayed(this, 16);
                } else {
                    isRotating = false;
                }
            }
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

这就是旋转标记的方式,我不知道这是否是最好的代码。但是我认为这样可以防止错误的轮换。编辑:添加var isRotating(感谢@Tr?n V?n Huy)

更新说明:
在此处输入图片说明 在此处输入图片说明 在此处输入图片说明 在此处输入图片说明 在此处输入图片说明