Animating Markers on Google Maps V2

Animate the rotation of the Marker in google map v2

static public void rotateMarker(final Marker marker, final float toRotation, GoogleMap map) {
final Handler handler = new Handler();
final long start = SystemClock.uptimeMillis();
final float startRotation = marker.getRotation();
final long duration = 1555;

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);

float rot = t * toRotation + (1 -t) * startRotation;

marker.setRotation(-rot > 180 ? rot/2 : rot);
if (t < 1.0) {
// Post again 16ms later.
handler.postDelayed(this, 16);
}
}
});
}

i have managed to do it :)

Animating markers on Google Maps v2

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.

Add animation as Marker google maps android

As far as I know, Google map Marker and InfoWindow is drawn on the map as a flat bitmap. So you cannot do animation, component touch interaction or even draw a shadow around them officially.

Uber app uses a different layer placed on top of the map (You can try to do some gesture on the map and see that the marker move but a bit delay). It's not easy because you have to catch every map's gesture and animate the overlay view accordingly. I tried that before but it's too much work to do so I left it behind.

Your Pulse effect can be achieved using Circle with ValueAnimator

private @ColorInt int mPulseEffectColor;
private int[] mPulseEffectColorElements;
private ValueAnimator mPulseEffectAnimator;
private Circle mPulseCircle;

private void initPulseEffect() {
mPulseEffectColor = ContextCompat.getColor(mContext, R.color.pink);
mPulseEffectColorElements = new int[] {
Color.red(mPulseEffectColor),
Color.green(mPulseEffectColor),
Color.blue(mPulseEffectColor)
};

mPulseEffectAnimator = ValueAnimator.ofFloat(0, calculatePulseRadius(current_map_zoom_level));
mPulseEffectAnimator.setStartDelay(3000);
mPulseEffectAnimator.setDuration(400);
mPulseEffectAnimator.setInterpolator(new AccelerateDecelerateInterpolator());
}

Calculate radius base on map's zoom level

private static float calculatePulseRadius(float zoomLevel) {
return (float) Math.pow(2, 16 - zoomLevel) * 160;
}

Register OnCameraIdleListener to listen to map's zoom changed

@Override
public void onCameraIdle() {
CameraPosition cameraPosition = mMap.getCameraPosition();
if (mPulseEffectAnimator != null)
mPulseEffectAnimator.setFloatValues(0, calculatePulseRadius(cameraPosition.zoom));
}

Start the animation

private void startPulseAnimation() {
if (mPulseCircle != null)
mPulseCircle.remove();

if (mPulseEffectAnimator != null) {
mPulseEffectAnimator.removeAllUpdateListeners();
mPulseEffectAnimator.removeAllListeners();
mPulseEffectAnimator.end();
}

if (your_marker_coordinate != null) {
mPulseCircle = mMap.addCircle(new CircleOptions()
.center(your_marker_coordinate)
.radius(0).strokeWidth(0)
.fillColor(mPulseEffectColor));
mPulseEffectAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
if (mPulseCircle == null)
return;

int alpha = (int) ((1 - valueAnimator.getAnimatedFraction()) * 128);
mPulseCircle.setFillColor(Color.argb(alpha,
mPulseEffectColorElements[0], mPulseEffectColorElements[1], mPulseEffectColorElements[2]));
mPulseCircle.setRadius((float) valueAnimator.getAnimatedValue());
}
});
mPulseEffectAnimator.addListener(new AnimatorListenerAdapter {
@Override
public void onAnimationEnd(Animator animation) {
mPulseEffectAnimator.setStartDelay(2000);
mPulseEffectAnimator.start();
}
});
mPulseEffectAnimator.start();
}
}

Explanation:

  • Use calculatePulseRadius to recalculate the radius base on the map zoom level, because the circle's radius is measured by the real-world distance.
  • Use int[] mPulseEffectColorElements to store r,g,b of the circle color so I don't have to recreate the color every frame. I only want to change the alpha value
  • Listen to Animator end and start it again with delay.

This code only applied for 1 circle at a time, multiple circles require harder work but same logic.

Result:

demo

Google Map v2 Marker Animation

I found a solution that worked for me:

final LatLng target = NEW_LOCATION;

final long duration = 400;
final Handler handler = new Handler();
final long start = SystemClock.uptimeMillis();
Projection proj = map.getProjection();

Point startPoint = proj.toScreenLocation(marker.getPosition());
final LatLng startLatLng = proj.fromScreenLocation(startPoint);

final Interpolator interpolator = new LinearInterpolator();
handler.post(new Runnable() {
@Override
public void run() {
long elapsed = SystemClock.uptimeMillis() - start;
if (elapsed > duration) {
elapsed = duration;
}
float t = interpolator.getInterpolation((float) elapsed / duration);
double lng = t * target.longitude + (1 - t) * startLatLng.longitude;
double lat = t * target.latitude + (1 - t) * startLatLng.latitude;
marker.setPosition(new LatLng(lat, lng));
if (t < 1.0) {
// Post again 10ms later.
handler.postDelayed(this, 10);
} else {
// animation ended
}
}
});

Is it possible add animation icon marker on Google map android api?

Hope you will get a better solution from here.

On that link there is a question to how to Animating markers on Google Maps V2

Google Map v2 Marker Animation

I found a solution that worked for me:

final LatLng target = NEW_LOCATION;

final long duration = 400;
final Handler handler = new Handler();
final long start = SystemClock.uptimeMillis();
Projection proj = map.getProjection();

Point startPoint = proj.toScreenLocation(marker.getPosition());
final LatLng startLatLng = proj.fromScreenLocation(startPoint);

final Interpolator interpolator = new LinearInterpolator();
handler.post(new Runnable() {
@Override
public void run() {
long elapsed = SystemClock.uptimeMillis() - start;
if (elapsed > duration) {
elapsed = duration;
}
float t = interpolator.getInterpolation((float) elapsed / duration);
double lng = t * target.longitude + (1 - t) * startLatLng.longitude;
double lat = t * target.latitude + (1 - t) * startLatLng.latitude;
marker.setPosition(new LatLng(lat, lng));
if (t < 1.0) {
// Post again 10ms later.
handler.postDelayed(this, 10);
} else {
// animation ended
}
}
});


Related Topics



Leave a reply



Submit