Animating markers on Google Maps v2

65,931

Solution 1

Some Google engineers have provided a nice demo video with some elegant sample code about how to animate markers from a starting point to an ending point, for all various versions of Android:

The relevant code is here:

https://gist.github.com/broady/6314689

And a nice demo video of all of it in action.

http://youtu.be/WKfZsCKSXVQ

OLD DEPRECATED ANSWER BELOW

In the documentation, it is mentioned that Marker Icons cannot be changed:

Icon

A bitmap that's displayed for the marker. If the icon is left unset, a default icon is displayed. You can specify an alternative coloring of the default icon using defaultMarker(float). You can't change the icon once you've created the marker.

Google Maps API v2 Documentation

You're going to have to keep track of specific markers, perhaps using a method similar to that described here: Link a Marker to an Object, then figure out which marker you need to update. Call .remove() on the marker, then create a rotated image depending on the "direction" you want, create a new Marker with that image, and add the new Marker to the map.

You do not need to "clear" the map, simply remove the marker you want to modify, create a new one, then add it back to the map.

Unfortunately, the new Maps API is not very flexible yet. Hopefully Google continues to improve upon it.

Solution 2

Full Example for DiscDev's answer (Above):

LatLng fromLocation = new LatLng(38.5, -100.4); // Whatever origin coordinates
LatLng toLocation = new LatLng(37.7, -107.7); // Whatever destination coordinates
Marker marker = mMap.addMarker(new MarkerOptions().position(firstLocation));
MarkerAnimation.animateMarkerToICS(marker, toLocation, new LatLngInterpolator.Spherical());

And for those of you who uses GPS / or any position provider that receives location updates:

Marker ourGlobalMarker;
// We've got a location from some provider of ours, now we can call:
private void updateMarkerPosition(Location newLocation) {

    LatLng newLatLng = new LatLng(newLocation.getLatitude(), newLocation.getLongitude());
    
    if(ourGlobalMarker == null) { // First time adding marker to map
        ourGlobalMarker = mMap.addMarker(new MarkerOptions().position(newLatLng));
    }
    else {
        MarkerAnimation.animateMarkerToICS(ourGlobalMarker, newLatLng, new LatLngInterpolator.Spherical());
    }         
}

IMPORTANT:

Within 1MarkerAnimation.java If the animation duration is set to X, and you are receiving location updates in a rate smaller then X, multiple animations will be triggered, and you might see the marker animation flickers a bit (which is not a nice user experience).

To avoid this, the animationMarkerToICS method (I took here animationMarkerToICS for example), should look something like this,

full method implementation:

private static Animator animator; // MAKING ANIMATOR GLOBAL INSTEAD OF LOCAL TO THE STATIC FUNCTION

...

// Ice Cream Sandwich compatible
@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
public static void animateMarkerToICS(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");

    // ADD THIS TO STOP ANIMATION IF ALREADY ANIMATING TO AN OBSOLETE LOCATION
    if(animator != null && animator.isRunning()) {
        animator.cancel();
        animator = null;
    }
    animator = ObjectAnimator.ofObject(marker, property, typeEvaluator, finalPosition);
    animator.setDuration((long) ANIMATION_DURATION);
    animator.start();
}

Enjoy.

Solution 3

Marker has a new function added as of rev.7 of API v2. Marker.setIcon, so you can use multiple icons to show direction.

Share:
65,931
Maksim Golivkin
Author by

Maksim Golivkin

Updated on August 01, 2021

Comments

  • Maksim Golivkin
    Maksim Golivkin almost 3 years

    What is the best way to animate markers on Google Maps using v2 API?

    I am working on a map-centered game where I track locations of people and display them on the map for each other to see. As people move, I want to animate a marker from his current to his latest position. Every person has a direction, so I need to rotate the marker appropriately.

    What is the best way to do it using the new Google Maps API?

  • mrroboaat
    mrroboaat over 10 years
    Have you ever tried animation with setIcon ? In my case, sometimes the blink is bad (too fast or slow) ...
  • MaciejGórski
    MaciejGórski over 10 years
    @aat I know there are still problems with it. It's IPC call after all. Maybe Googlers can add real animation support like they did for iOS.
  • DiscDev
    DiscDev over 10 years
    @Ted - I did some searching around and found a "real" answer and updated my post. Check it out above, it's pretty neat and easy to understand.
  • Sophie
    Sophie over 6 years
    how can we set the zoom level ?
  • Mercury
    Mercury over 6 years
    Zoom is not relevant to this question, please take a look here for zoom
  • Arindam Mukherjee
    Arindam Mukherjee over 5 years
    I have used this code. But I am getting multiple markers. Older markers are not hiding when car has moved. Can you please tell me how to use this "hideMarker" value properly.
  • Arjun
    Arjun almost 3 years
    I'm getting the following error: android.util.NoSuchPropertyException: No accessor method or field found for property with name position