javaandroidgoogle-mapsgpsgoogle-maps-markers

How to correct smooth moving the marker in google maps v2?


In my application based on one from https://github.com/googlemaps/android-samples needs to display a smooth "move" google maps marker from one point to another. I use the following method for the animation:

public void animateMarker(final Marker marker, final LatLng toPosition,
                          final boolean hideMarker) {
    final Handler handler = new Handler();
    final long start = SystemClock.uptimeMillis();
    Projection proj = mMap.getProjection();
    Point startPoint = proj.toScreenLocation(marker.getPosition());
    final LatLng startLatLng = proj.fromScreenLocation(startPoint);
    final long duration = 500;

    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);
            double lng = t * toPosition.longitude + (1 - t)
                    * startLatLng.longitude;
            double lat = t * toPosition.latitude + (1 - t)
                    * startLatLng.latitude;
            marker.setPosition(new LatLng(lat, lng));

            if (t < 1.0) {
                // Post again 16ms later.
                handler.postDelayed(this, 16);
            } else {
                if (hideMarker) {
                    marker.setVisible(false);
                } else {
                    marker.setVisible(true);
                }
            }
        }
    });
}

But as a result of simply creating a new marker to the new location (though old is not removed):

enter image description here


Solution

  • I copied some of the code from the project mentioned in the official video.

    I tried to reproduce it with this code and this seems to be working for me, so hopefully my code would help you, even for a bit.

    static final LatLng SomePos = new LatLng(37.7796354, -122.4159606);
    
        try {
            if (googleMap == null) {
                googleMap = ((MapFragment) getFragmentManager().findFragmentById(R.id.map)).getMap();
            }
            googleMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
            googleMap.setMyLocationEnabled(true);
            googleMap.setTrafficEnabled(false);
            googleMap.setIndoorEnabled(false);
            googleMap.setBuildingsEnabled(true);
            googleMap.getUiSettings().setZoomControlsEnabled(true);
            googleMap.moveCamera(CameraUpdateFactory.newLatLng(SomePos));
            googleMap.moveCamera(CameraUpdateFactory.newCameraPosition(new CameraPosition.Builder()
                    .target(googleMap.getCameraPosition().target)
                    .zoom(17)
                    .bearing(30)
                    .tilt(45)
                    .build()));
    
            myMarker = googleMap.addMarker(new MarkerOptions()
                    .position(SomePos)
                    .icon(BitmapDescriptorFactory.fromResource(R.mipmap.ic_launcher))
                    .title("Hello world"));
    
    
            googleMap.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener()
            {
                @Override
                public boolean onMarkerClick(Marker arg0) {
    
                    final LatLng startPosition = myMarker.getPosition();
                    final LatLng finalPosition = new LatLng(37.7801569,-122.4148528);
                    final Handler handler = new Handler();
                    final long start = SystemClock.uptimeMillis();
                    final Interpolator interpolator = new AccelerateDecelerateInterpolator();
                    final float durationInMs = 3000;
                    final boolean hideMarker = false;
    
                    handler.post(new Runnable() {
                        long elapsed;
                        float t;
                        float v;
    
                        @Override
                        public void run() {
                            // Calculate progress using interpolator
                            elapsed = SystemClock.uptimeMillis() - start;
                            t = elapsed / durationInMs;
                            v = interpolator.getInterpolation(t);
    
                            LatLng currentPosition = new LatLng(
                                    startPosition.latitude*(1-t)+finalPosition.latitude*t,
                                    startPosition.longitude*(1-t)+finalPosition.longitude*t);
    
                            myMarker.setPosition(currentPosition);
    
                            // Repeat till progress is complete.
                            if (t < 1) {
                                // Post again 16ms later.
                                handler.postDelayed(this, 16);
                            } else {
                                if (hideMarker) {
                                    myMarker.setVisible(false);
                                } else {
                                    myMarker.setVisible(true);
                                }
                            }
                        }
                    });
    
                    return true;
    
                }
    
            });
    
        } catch (Exception e) {
            e.printStackTrace();
        }