My app shows a map and i want that users can\'t swipe over a certain region. So i\'m trying to add bounds but it makes the app to crash. Here is the working code:
I've created a way to combine the two callbacks: onMapReady and onGlobalLayout into one single observable which will emit only when both the events have been triggered.
https://gist.github.com/abhaysood/e275b3d0937f297980d14b439a8e0d4a
public final class OnMapAndLayoutReady {
private OnMapAndLayoutReady() {
}
/**
* Converts {@link OnMapReadyCallback} to an observable.
* Note that this method calls {@link MapView#getMapAsync(OnMapReadyCallback)} so you there is no
* need to initialize google map view manually.
*/
private static Observable loadMapObservable(final MapView mapView) {
return Observable.create(new Observable.OnSubscribe() {
@Override
public void call(final Subscriber super GoogleMap> subscriber) {
OnMapReadyCallback mapReadyCallback = new OnMapReadyCallback() {
@Override
public void onMapReady(GoogleMap googleMap) {
subscriber.onNext(googleMap);
}
};
mapView.getMapAsync(mapReadyCallback);
}
});
}
/**
* Converts {@link ViewTreeObserver.OnGlobalLayoutListener} to an observable.
* This methods also takes care of removing the global layout listener from the view.
*/
private static Observable globalLayoutObservable(final MapView view) {
return Observable.create(new Observable.OnSubscribe() {
@Override
public void call(final Subscriber super MapView> subscriber) {
final ViewTreeObserver.OnGlobalLayoutListener globalLayoutListener = new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
view.getViewTreeObserver().removeOnGlobalLayoutListener(this);
subscriber.onNext(view);
}
};
view.getViewTreeObserver().addOnGlobalLayoutListener(globalLayoutListener);
}
});
}
/**
* Takes {@link #globalLayoutObservable(MapView)} and {@link #loadMapObservable(MapView)} and zips their result.
* This means that the subscriber will only be notified when both the observables have emitted.
*/
public static Observable onMapAndLayoutReadyObservable(final MapView mapView) {
return Observable.zip(globalLayoutObservable(mapView), loadMapObservable(mapView), new Func2() {
@Override
public GoogleMap call(MapView mapView, GoogleMap googleMap) {
return googleMap;
}
});
}
}