I am trying to achieve a breathing effect animation on my MapFragment but for some reason, I cannot run multiple animations on the map. What I am trying to achieve is something like this:
And the circles are expanding gradually and fading away doing so. Right now my animation is doing this:
Which is not quite what I want. The current code (if I uncomment the 2 blocks with the handlers) is doing only one animation and the rest of the shapes are staying stationary. EDIT I found out what is going on - the "startAnimation" method is overriding the current animation. Now I am wondering if there is a way how I can avoid this overriding? Any ideas?:
This is my code:
@Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
//Add smallest image drawable overlay
mDotMarkerBitmap = generateBitmapFromDrawable(R.drawable.circle_drawable);
groundOverlay = mMap.addGroundOverlay(new GroundOverlayOptions()
.image(BitmapDescriptorFactory.fromBitmap(mDotMarkerBitmap))
.position(xDesign, 100));
groundAnimation = new RadiusAnimation(groundOverlay);
groundAnimation.setRepeatCount(Animation.INFINITE);
groundAnimation.setRepeatMode(Animation.RESTART);
groundAnimation.setDuration(2000);
mapFragment.getView().startAnimation(groundAnimation); // MapView where i show my map
//TODO Fix the animation tomorrow
//Add medium size image drawable overlay
// new Handler().postDelayed(new Runnable() {
// @Override
// public void run() {
// // your code here
// mDotMarkerBitmap = generateBitmapFromDrawable(R.drawable.circle_drawable2);
// groundOverlay = mMap.addGroundOverlay(new GroundOverlayOptions()
// .image(BitmapDescriptorFactory.fromBitmap(mDotMarkerBitmap))
// .position(xDesign, 100));
// groundAnimation = new RadiusAnimation(groundOverlay);
// groundAnimation.setRepeatCount(Animation.INFINITE);
// groundAnimation.setRepeatMode(Animation.RESTART);
// groundAnimation.setDuration(10000);
// mapFragment.getView().startAnimation(groundAnimation); // MapView where i show my map
// }
// }, 1000/* 1sec delay */);
//
////Add smallest size image drawable overlay
// new Handler().postDelayed(new Runnable()
// {
// @Override
// public void run()
// {
// // your code here
// mDotMarkerBitmap = generateBitmapFromDrawable(R.drawable.circle_drawable3);
// groundOverlay = mMap.addGroundOverlay(new GroundOverlayOptions()
// .image(BitmapDescriptorFactory.fromBitmap(mDotMarkerBitmap))
// .position(xDesign, 100));
// groundAnimation = new RadiusAnimation(groundOverlay);
// groundAnimation.setRepeatCount(Animation.INFINITE);
// groundAnimation.setRepeatMode(Animation.RESTART);
// groundAnimation.setDuration(2000);
// mapFragment.getView().startAnimation(groundAnimation); // MapView where i show my map
// }
// }, 1000/* 1sec delay */);
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(xDesign, 15));
}
circle_drawable.xml (circle_drawable2 and 3 are the same exept the width&height values, they are bigger 60 and 90dp and the colors - blue and red):
<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<solid
android:color="#0093e8"/>
<size
android:width="30dp"
android:height="30dp"/>
</shape>
RadiusAnimation class:
public class RadiusAnimation extends Animation {
private GroundOverlay groundOverlay;
public RadiusAnimation(GroundOverlay groundOverlay) {
this.groundOverlay = groundOverlay;
}
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
groundOverlay.setDimensions( (100 * interpolatedTime) );
groundOverlay.setTransparency( interpolatedTime );
}
@Override
public void initialize(int width, int height, int parentWidth,int parentHeight) {
super.initialize(width, height, parentWidth, parentHeight);
}
}
In case someone is trying to do something similar I found the solution. In order to run multiple animations at the same, I can use AnimationSet. So I removed the Handlers which were to delay the individual animations but since each one is overriding the last one it was not working and I was seeing the last one added playing on the mapFragment. So I changed my code like that:
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
//Add smallest image drawable overlay
Bitmap mDotMarkerBitmap1 = generateBitmapFromDrawable(R.drawable.circle_drawable);
GroundOverlay groundOverlay1 = mMap.addGroundOverlay(new GroundOverlayOptions()
.image(BitmapDescriptorFactory.fromBitmap(mDotMarkerBitmap1))
.position(xDesign, 100));
groundAnimation = new RadiusAnimation(groundOverlay1);
groundAnimation.setRepeatCount(Animation.INFINITE);
groundAnimation.setRepeatMode(Animation.RESTART);
// groundAnimation.setDuration(700);
breadingAnimations.addAnimation(groundAnimation);
Bitmap mDotMarkerBitmap2 = generateBitmapFromDrawable(R.drawable.circle_drawable2);
GroundOverlay groundOverlay2 = mMap.addGroundOverlay(new GroundOverlayOptions()
.image(BitmapDescriptorFactory.fromBitmap(mDotMarkerBitmap2))
.position(xDesign, 100));
Animation groundAnimation2 = new RadiusAnimation(groundOverlay2);
groundAnimation2.setRepeatCount(Animation.INFINITE);
groundAnimation2.setRepeatMode(Animation.RESTART);
// groundAnimation2.setDuration(900);
breadingAnimations.addAnimation(groundAnimation2);
Bitmap mDotMarkerBitmap3 = generateBitmapFromDrawable(R.drawable.circle_drawable3);
GroundOverlay groundOverlay3 = mMap.addGroundOverlay(new GroundOverlayOptions()
.image(BitmapDescriptorFactory.fromBitmap(mDotMarkerBitmap3))
.position(xDesign, 100));
Animation groundAnimation3 = new RadiusAnimation(groundOverlay3);
groundAnimation2.setRepeatCount(Animation.INFINITE);
groundAnimation2.setRepeatMode(Animation.RESTART);
// groundAnimation2.setDuration(1100);
breadingAnimations.addAnimation(groundAnimation3);
mapFragment.getView().startAnimation(breadingAnimations); // start animation
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(xDesign, 15));
}