Search code examples
androidgoogle-mapsmarkerobjectanimator

How to animate marker on google maps ?


What i'm trying to achieve supposed to be very simple, yet it's not working. I have added a marker on my map, and i'm trying to animate it an heart beat.

I have tried the following code, but without no luck,

   ObjectAnimator pulse = ObjectAnimator.ofPropertyValuesHolder(userLocation,
            PropertyValuesHolder.ofFloat("scaleX",2f),
            PropertyValuesHolder.ofFloat("scaleY",2f)
            );
    pulse.setDuration(310);
    pulse.setRepeatCount(ObjectAnimator.INFINITE);
    pulse.setRepeatMode(ObjectAnimator.REVERSE);
    pulse.start();

any suggestion would be grateful, plus using an external library can be an option as well, I have just didn't find one.


Solution

  • General approach well described in Cabezas answer. In addition to his answer, for your task You should apply it for setting (resized according Interpolator for each frame of animation) bitmap for marker. For example, You can do it by using method like this:

    private void pulseMarker(final Bitmap markerIcon, final Marker marker, final long onePulseDuration) {
        final Handler handler = new Handler();
        final long startTime = System.currentTimeMillis();
    
        final Interpolator interpolator = new CycleInterpolator(1f);
        handler.post(new Runnable() {
            @Override
            public void run() {
                long elapsed = System.currentTimeMillis() - startTime;
                float t = interpolator.getInterpolation((float) elapsed / onePulseDuration);
                marker.setIcon(BitmapDescriptorFactory.fromBitmap(scaleBitmap(markerIcon, 1f + 0.05f * t)));
                handler.postDelayed(this, 16);
            }
        });
    }
    

    where 16 is duration of one frame of animation, 1f + 0.05f * t - is 5% increase and decrease of size of marker icon and scaleBitmap() is:

    public Bitmap scaleBitmap(Bitmap bitmap, float scaleFactor) {
        final int sizeX = Math.round(bitmap.getWidth() * scaleFactor);
        final int sizeY = Math.round(bitmap.getHeight() * scaleFactor);
        Bitmap bitmapResized = Bitmap.createScaledBitmap(bitmap, sizeX, sizeY, false);
        return bitmapResized;
    }
    

    and call is:

    Bitmap markerIcon = BitmapFactory.decodeResource(getResources(), R.drawable.ic_heart);
    pulseMarker(markerIcon, marker, 1000);
    

    where marker is your marker, 1000 - 1 sec duration of one pulse.