Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bounce marker continuously: android maps v2

after searching on how to bounce a marker in android maps v2, only one method i found everywhere and its working fine. But only on a marker click, what i need is to make marker bounce continuously like it'll do in JavaScript maps v3. How can i achieve this?

code below:

map.setOnMarkerClickListener(new OnMarkerClickListener() {

            @Override
            public boolean onMarkerClick(Marker arg0) {
                arg0.showInfoWindow();
                bounceMarker(arg0);
                return true;
            }
        });

private void bounceMarker(final Marker marker){
        final Handler handler = new Handler();

        final long startTime = SystemClock.uptimeMillis();
        final long duration = 1500;

        Projection proj = busmap.getProjection();
        final LatLng markerLatLng = marker.getPosition();
        Point startPoint = proj.toScreenLocation(markerLatLng);
        startPoint.offset(0, -100);
        final LatLng startLatLng = proj.fromScreenLocation(startPoint);

        final Interpolator interpolator = new BounceInterpolator();

        handler.post(new Runnable() {
            @Override
            public void run() {
                long elapsed = SystemClock.uptimeMillis() - startTime;
                float t = interpolator.getInterpolation((float) elapsed / duration);
                double lng = t * markerLatLng.longitude + (1 - t) * startLatLng.longitude;
                double lat = t * markerLatLng.latitude + (1 - t) * startLatLng.latitude;
                marker.setPosition(new LatLng(lat, lng));

                if (t < 1.0) {
                    // Post again 16ms later.
                    handler.postDelayed(this, 16);
                }
            }
        });

}
like image 455
Jarvis Avatar asked Jan 21 '26 03:01

Jarvis


2 Answers

Here's another way of achieving this. I borrowed a lot from M D's solution, which is very smart in that it uses the Marker's anchor instead of actually changing the Marker's LatLng in the interpolator, but it's actually a hybrid of Jarvis's code and M D's with small modifications. I don't use a TimerTask at all, but rather create a method to make the Marker bounce and and sort of call it recursively, which makes the code much more compact. I'm not sure if there are any negative implications to this, but it works, so I'll post it for anyone who doesn't want to create a TimerTask, but rather just wants the animation to loop continuously:

private void setMarkerBounce(final Marker marker) {
    final Handler handler = new Handler();
    final long startTime = SystemClock.uptimeMillis();
    final long duration = 2000;
    final Interpolator interpolator = new BounceInterpolator();
    handler.post(new Runnable() {
        @Override
        public void run() {
            long elapsed = SystemClock.uptimeMillis() - startTime;
            float t = Math.max(1 - interpolator.getInterpolation((float) elapsed/duration), 0);
            marker.setAnchor(0.5f, 1.0f +  t);

            if (t > 0.0) {
                handler.postDelayed(this, 16);
            } else {
                setMarkerBounce(marker);
            }
        }
    });
}
like image 198
ethan123 Avatar answered Jan 23 '26 19:01

ethan123


Hey Javis here is your solution below code is perfect working in my case. First add this:

 static final LatLng SECC = new LatLng(55.8607, -4.2871);
 private Marker mPerth;

now, add Marker into map:

mPerth = mMap
                .addMarker(new MarkerOptions()
                        .position(SECC)
                        .title("SECC")
                        .snippet(
                                "Exhibition Way, Glasgow, G3 8YW\nSports: Boxing, Gymnastics, Judo, Netball, Wrestling, Weightlifting"));

        Timer timer = new Timer();
        TimerTask updateProfile = new CustomTimerTask(Stacky.this); 
        timer.scheduleAtFixedRate(updateProfile, 10,5000);

        mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(SECC, 18.0f));

at last add CustomTimeTask this will continue to call t every 15 second:

class CustomTimerTask extends TimerTask {
    private Context context;
    private Handler mHandler = new Handler();

    // Write Custom Constructor to pass Context
    public CustomTimerTask(Context con) {
        this.context = con;
    }

    @Override
    public void run() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                mHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        final Handler handler = new Handler();
                        final long start = SystemClock.uptimeMillis();
                        final long duration = 1500;

                        final Interpolator interpolator = new BounceInterpolator();

                        handler.post(new Runnable() {
                            @Override
                            public void run() {
                                long elapsed = SystemClock.uptimeMillis() - start;
                                float t = Math.max(
                                        1 - interpolator.getInterpolation((float) elapsed
                                                / duration), 0);
                                mPerth.setAnchor(0.5f, 1.0f + 2 * t);

                                if (t > 0.0) {
                                    // Post again 16ms later.
                                    handler.postDelayed(this, 16);
                                }
                            }
                        });
                    }
                });
            }
        }).start();

    }

}

i hope this will help you.

like image 29
M D Avatar answered Jan 23 '26 21:01

M D



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!