Android Google Maps v2 Camera Animation

20,295

Solution 1

I have the same problem when i want to move camera to the same position, it seems like a bug. Even if old and new position are not the same and the difference is so small , ex: old position.latitude = 94.54284009112, new position.latitude = 94.54284003451, it dosen't work. my solution is to truncate values to get only old_position.latitude = new_position.latitude = 94.54, then i do a test.

There is another problem with moving camera and scroll the map in the same time, for that i disable scroll gesture before moving and enable it on the onFinish() and the onCancel().

public void animateCameraTo(final double lat, final double lng)
{
    _googleMap = getMap();
    CameraPosition camPosition = _googleMap.getCameraPosition();
    if (!((Math.floor(camPosition.target.latitude * 100) / 100) == (Math.floor(lat * 100) / 100) && (Math.floor(camPosition.target.longitude * 100) / 100) == (Math.floor(lng * 100) / 100)))
    {
        _googleMap.getUiSettings().setScrollGesturesEnabled(false);
        _googleMap.animateCamera(CameraUpdateFactory.newLatLng(new LatLng(lat, lng)), new CancelableCallback()
        {

            @Override
            public void onFinish()
            {
                _googleMap.getUiSettings().setScrollGesturesEnabled(true);

            }

            @Override
            public void onCancel()
            {
                _googleMap.getUiSettings().setAllGesturesEnabled(true);

            }
        });
    }

}

Hope this helps you ;)

Solution 2

Your should check the pixel distance, not the geo distance:

LatLngBounds myBounds = YOUR_BOUNDS;
LatLngBounds visibleBounds = map.getProjection().getVisibleRegion().latLngBounds;
Point myCenter = map.getProjection().toScreenLocation(myBounds.getCenter());
Point visibleCenter = map.getProjection().toScreenLocation(visibleBounds.getCenter());
int dist = (int) Math.sqrt(Math.pow(myCenter.x - visibleCenter.x, 2) + Math.pow(myCenter.y - visibleCenter.y, 2));
if (dist > YOUR_THRESHOLD) {
    map.animateCamera(CameraUpdateFactory.newLatLngBounds(myBounds, YOUR_PADDING), new GoogleMap.CancelableCallback() {
        @Override
        public void onFinish() {
            // do something
        }

        @Override
        public void onCancel() {
            // do something
        }
    });
} else {
    // do something
}
Share:
20,295
Aiden Fry
Author by

Aiden Fry

Updated on July 09, 2022

Comments

  • Aiden Fry
    Aiden Fry almost 2 years

    So im not sure if this is a bug or not yet... might be or I may have missed something.

    Anyway so here is the link to Google Maps V2 Camera Controls. https://developers.google.com/maps/documentation/android/views#moving_the_camera

    The issue :

    Animate to a location already animated to does not call onFinish();

    How to replicate:

    mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(mLocation.getLatLng(), zoomLevel), 200, new GoogleMap.CancelableCallback() {
    
                        @Override
                        public void onFinish() {
                            //DO some stuff here!
                        Log.d("animation", "onFinishCalled");
    
                        }
    
                        @Override
                        public void onCancel() {
                        Log.d("animation", "onCancel");
    
    
                        }
                    }); 
    

    This issue may well come about when a user double taps something which called the same animation even if there is a long time between, onFinish will only be called for a successful animation. When the camera is already positioned the onFinish method will not be called!

    I could go around doing checks before I do any camera animation but I don't like that as its wasteful.

    Any help would be appreciated. Thanks.

  • Aiden Fry
    Aiden Fry about 11 years
    Nope, iv moved to moveCamera rather than animateCamera which kinda sucks :(
  • Aiden Fry
    Aiden Fry about 11 years
    The only alternative i can think off (similar to yours) is to check if the LatLng you are animating to is the same as Camera target position before starting the animation. if it is do your onFinished methods. Your rects are likely being null'd when you rotate. Look at this developer.android.com/guide/topics/resources/… might help
  • Aiden Fry
    Aiden Fry about 11 years
    fair point, good work around, i would go down to at least 4 decimal points though! 2 decimals on lat long is quite a large area still
  • Graham
    Graham almost 10 years
    The rounding of lat/long values to the nearest 100th is seemingly arbitrary and results in different behavior depending on the zoom level. A better solution would incorporate the zoom level for determining the amount to round by.