You're on the right track by animating the Marker object rather than adding and removing Views in front of the GoogleMap, but you can get better performance if you use an Animator object to animate the Marker.
With the Handler and delayed Runnable approach, you're effectively hard coding a target frame rate. If you post the Runnable with too low of a delay, your animation will take longer to execute. If too high, the frame rate will be too slow, and it'll look choppy even on powerful devices. The advantage to using an Animator over a Handler and delayed Runnable is that it will only call onAnimationUpdate() to draw the next frame as often as the system can handle.
In my clustering library, Clusterkraf, I used an ObjectAnimator (from NineOldAndroids for backwards compatibility) to animate cluster transitions when changing zoom level. It can smoothly animate around 100 markers on my Galaxy Nexus.
Below is a snippet with an overview of how to make that work.
class ClusterTransitionsAnimation implements AnimatorListener, AnimatorUpdateListener {
private ObjectAnimator animator;
private AnimatedTransitionState state;
private ClusterTransitions transitions;
private Marker[] animatedMarkers;
void animate(ClusterTransitions transitions) {
if (this.state == null) {
Options options = optionsRef.get();
Host host = hostRef.get();
if (options != null && host != null) {
this.state = new AnimatedTransitionState(transitions.animated);
this.transitions = transitions;
animator = ObjectAnimator.ofFloat(this.state, "value", 0f, 1f);
animator.addListener(this);
animator.addUpdateListener(this);
animator.setDuration(options.getTransitionDuration());
animator.setInterpolator(options.getTransitionInterpolator());
host.onClusterTransitionStarting();
animator.start();
}
}
}
@Override
public void onAnimationStart(Animator animator) {
// Add animatedMarkers to map, omitted for brevity
}
@Override
public void onAnimationUpdate(ValueAnimator animator) {
if (state != null && animatedMarkers != null) {
LatLng[] positions = state.getPositions();
for (int i = 0; i < animatedMarkers.length; i++) {
animatedMarkers[i].setPosition(positions[i]);
}
}
}
}