Shaky Google Maps Marker Animation

I am trying to animate markers on a Google Map. The problem I am facing is how markers behave when it is time to revive them. Markers move along a given set of points, but they begin to tremble a lot, or they will move along a given path and, apparently, will have an elastic band or return to their original starting position.

Has anyone dealt with this issue before? and if so, how did you fix it? I am currently using a slightly modified version of the code provided by Google developers to handle the animation.

UPDATE: I believe that the problem is caused by an attempt to run many animations simultaneously on a given marker. This causes the marker to go back and forth between all new / old positions.

Here is the code that handles Animation calls, the method is passed a list of LatLngs that represent the path that the marker should follow.

public void animateMarker(String key, List<LatLng> latlngList) {
    AnimateCarObj animateCarObj = animateCarObjMap.get(key);
    Marker marker = markersHashMap.get(key);

    if (marker != null) {

        LatLng prev = new LatLng(0, 0);
        for (LatLng latlng : latlngList) {
            if (!(latlng.equals(prev))) {
                try {
                    LatLngInterpolator latlonInter = new LinearFixed();
                    latlonInter.interpolate(1, animateCarObj.getGps1(), latlng);

                    MarkerAnimation.animateMarker(latlngList.size(), marker, latlng, latlonInter);
                    prev = latlng;

                } catch (Exception e) {
                    Log.e(TAG, "EXCEPTION: " + e.getMessage());
                    e.printStackTrace();
                }
            }
        }
    }
}

MarkerAnimation class , I modified this class to accept an Integer value called "steps", which means that the animation will go through all the points at an even pace, regardless of how many points are returned through the request. In this example, it uses the default value of 3, multiplies it by 10000 ms and divides it by the number of steps.

public class MarkerAnimation {

    public static void animateMarker(int steps, final Marker marker, final LatLng finalPosition,
                                                                        final LatLngInterpolator latLngInterpolator) {
        if (marker == null || finalPosition == null || latLngInterpolator == null) { return; }
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB_MR1) {
            animateMarkerToGB(steps, marker, finalPosition, latLngInterpolator);
        } else {
            animateMarkerToICS(steps, marker, finalPosition, latLngInterpolator);
        }
    }

    public static void animateMarkerToGB(int steps, final Marker marker, final LatLng finalPosition,
                                                                                final LatLngInterpolator latLngInterpolator) {
        final LatLng startPosition = marker.getPosition();
        final Handler handler = new Handler();
        final long start = SystemClock.uptimeMillis();
        final Interpolator interpolator = new AccelerateDecelerateInterpolator();
        final float durationInMs = (CarListStore.DEFAULT_ALIVE_COUNT * 10000) / steps;

        handler.post(new Runnable() {
            long elapsed;
            float t;
            float v;

            @Override
            public void run() {
                // Calculate progress using interpolator
                elapsed = SystemClock.uptimeMillis() - start;
                t = elapsed / durationInMs;
                v = interpolator.getInterpolation(t);

                marker.setPosition(latLngInterpolator.interpolate(v, startPosition, finalPosition));

                // Repeat till progress is complete.
                if (t < 1) {
                    // Post again 16ms later.
                    handler.postDelayed(this, 16);
                }
            }
        });
    }

    /*  @TargetApi(Build.VERSION_CODES.HONEYCOMB)
        public static void animateMarkerToHC(final Marker marker, final LatLng finalPosition,
                                                                                    final LatLngInterpolator latLngInterpolator) {
            final LatLng startPosition = marker.getPosition();

            ValueAnimator valueAnimator = new ValueAnimator();
            valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                @Override
                public void onAnimationUpdate(ValueAnimator animation) {
                    float v = animation.getAnimatedFraction();
                    LatLng newPosition = latLngInterpolator.interpolate(v, startPosition, finalPosition);
                    marker.setPosition(newPosition);
                }
            });
            valueAnimator.setFloatValues(0, 1); // Ignored.
            valueAnimator.setDuration(3000);
            valueAnimator.start();
        }*/

    @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
    public static void animateMarkerToICS(int steps, Marker marker, LatLng finalPosition, final LatLngInterpolator latLngInterpolator) {
        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, finalPosition);
        animator.setDuration((CarListStore.DEFAULT_ALIVE_COUNT * 10000) / steps);
        animator.start();
    }
}
+4
source share
2

, , .

i.e [valueAnimator][1] - . , , .

, !

0

Runnable, . , OnComplete , runnable, latlng .

ICS HC animator.start() handler.postDelayed(),

0

All Articles