How to fix smooth marker movement in google maps v2?

My application should display a smooth google map marker "move" from one point to another. For animation, I use the following method:

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 simple creation of a new marker in a new place (although the old one is not deleted):

enter image description here

+5
source share
2 answers

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

I tried to play it using this code, and this one works for me , so hopefully my code will help you, even a little.

 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(); } 
+18
source

I know this is an old question, but ...

For this task, you can use the value interpolator:

 fun changePositionSmoothly(marker:Marker?, newLatLng: LatLng){ if(marker == null){ return; } val animation = ValueAnimator.ofFloat(0f, 100f) var previousStep = 0f val deltaLatitude = newLatLng.latitude - marker.position.latitude val deltaLongitude = newLatLng.longitude - marker.position.longitude animation.setDuration(1500) animation.addUpdateListener { updatedAnimation -> val deltaStep = updatedAnimation.getAnimatedValue() as Float - previousStep previousStep = updatedAnimation.getAnimatedValue() as Float marker.position = LatLng(marker.position.latitude + deltaLatitude * deltaStep * 1/100, marker.position.longitude + deltaStep * deltaLongitude * 1/100) } animation.start() } 

To prevent the accumulation of errors, at the end of the animation you can set a new position, but this is enough for most cases.

+3
source

Source: https://habr.com/ru/post/1216205/


All Articles