package com.airbnb.android.airmapview;
import android.content.Context;
import android.support.annotation.NonNull;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.widget.FrameLayout;
import com.airbnb.android.airmapview.listeners.InfoWindowCreator;
import com.airbnb.android.airmapview.listeners.OnCameraChangeListener;
import com.airbnb.android.airmapview.listeners.OnCameraMoveListener;
import com.airbnb.android.airmapview.listeners.OnInfoWindowClickListener;
import com.airbnb.android.airmapview.listeners.OnLatLngScreenLocationCallback;
import com.airbnb.android.airmapview.listeners.OnMapBoundsCallback;
import com.airbnb.android.airmapview.listeners.OnMapClickListener;
import com.airbnb.android.airmapview.listeners.OnMapInitializedListener;
import com.airbnb.android.airmapview.listeners.OnMapLoadedListener;
import com.airbnb.android.airmapview.listeners.OnMapMarkerClickListener;
import com.airbnb.android.airmapview.listeners.OnMapMarkerDragListener;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.LatLngBounds;
import com.google.android.gms.maps.model.Marker;
import org.json.JSONException;
public class AirMapView extends FrameLayout
implements OnCameraChangeListener, OnMapClickListener, OnMapMarkerDragListener,
OnMapMarkerClickListener, OnMapLoadedListener, OnInfoWindowClickListener {
private static final int INVALID_ZOOM = -1;
protected AirMapInterface mapInterface;
private OnCameraMoveListener onCameraMoveListener;
private OnCameraChangeListener onCameraChangeListener;
private boolean mOnCameraMoveTriggered;
private OnMapInitializedListener onMapInitializedListener;
private OnMapMarkerClickListener onMapMarkerClickListener;
private OnMapMarkerDragListener onMapMarkerDragListener;
private OnMapClickListener onMapClickListener;
private OnInfoWindowClickListener onInfoWindowClickListener;
public AirMapView(Context context) {
super(context);
inflateView();
}
public AirMapView(Context context, AttributeSet attrs) {
super(context, attrs);
inflateView();
}
public AirMapView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
inflateView();
}
private void inflateView() {
LayoutInflater.from(getContext()).inflate(R.layout.map_view, this);
}
public void initialize(FragmentManager fragmentManager, AirMapInterface mapInterface) {
if (mapInterface == null || fragmentManager == null) {
throw new IllegalArgumentException("Either mapInterface or fragmentManager is null");
}
this.mapInterface = mapInterface;
this.mapInterface.setOnMapLoadedListener(this);
fragmentManager.beginTransaction()
.replace(getId(), (Fragment) this.mapInterface)
.commit();
fragmentManager.executePendingTransactions();
}
/**
* Used for initialization of the underlying map provider.
*
* @param fragmentManager required for initialization
*/
public void initialize(FragmentManager fragmentManager) {
AirMapInterface mapInterface = (AirMapInterface)
fragmentManager.findFragmentById(R.id.map_frame);
if (mapInterface != null) {
initialize(fragmentManager, mapInterface);
} else {
initialize(fragmentManager, new DefaultAirMapViewBuilder(getContext()).builder().build());
}
}
public void setOnMapInitializedListener(OnMapInitializedListener mapInitializedListener) {
onMapInitializedListener = mapInitializedListener;
}
@Override public boolean dispatchTouchEvent(@NonNull MotionEvent ev) {
if (ev.getAction() == MotionEvent.ACTION_MOVE) {
if (onCameraMoveListener != null && !mOnCameraMoveTriggered) {
onCameraMoveListener.onCameraMove();
mOnCameraMoveTriggered = true;
}
} else if (ev.getAction() == MotionEvent.ACTION_UP) {
mOnCameraMoveTriggered = false;
}
return super.dispatchTouchEvent(ev);
}
public void setOnCameraChangeListener(OnCameraChangeListener onCameraChangeListener) {
this.onCameraChangeListener = onCameraChangeListener;
}
/**
* Sets the map {@link com.airbnb.android.airmapview.listeners.OnCameraMoveListener}
*
* @param onCameraMoveListener The OnCameraMoveListener to be set
*/
public void setOnCameraMoveListener(OnCameraMoveListener onCameraMoveListener) {
this.onCameraMoveListener = onCameraMoveListener;
}
public final AirMapInterface getMapInterface() {
return mapInterface;
}
public void onDestroyView() {
if (isInitialized()) {
mapInterface.setMyLocationEnabled(false);
}
}
public int getZoom() {
if (isInitialized()) {
return mapInterface.getZoom();
}
return INVALID_ZOOM;
}
public LatLng getCenter() {
if (isInitialized()) {
return mapInterface.getCenter();
}
return null;
}
public boolean setCenter(LatLng latLng) {
if (isInitialized()) {
mapInterface.setCenter(latLng);
return true;
}
return false;
}
public boolean animateCenter(LatLng latLng) {
if (isInitialized()) {
mapInterface.animateCenter(latLng);
return true;
}
return false;
}
public boolean setZoom(int zoom) {
if (isInitialized()) {
mapInterface.setZoom(zoom);
return true;
}
return false;
}
public boolean setCenterZoom(LatLng latLng, int zoom) {
if (isInitialized()) {
mapInterface.setCenterZoom(latLng, zoom);
return true;
}
return false;
}
public boolean animateCenterZoom(LatLng latLng, int zoom) {
if (isInitialized()) {
mapInterface.animateCenterZoom(latLng, zoom);
return true;
}
return false;
}
public boolean setBounds(LatLngBounds latLngBounds, int boundsPadding) {
if (isInitialized()) {
mapInterface.setCenter(latLngBounds, boundsPadding);
return true;
}
return false;
}
public void getScreenBounds(OnMapBoundsCallback callback) {
if (isInitialized()) {
mapInterface.getMapScreenBounds(callback);
}
}
public void getMapMarkerScreenLocation(LatLng latLng, OnLatLngScreenLocationCallback callback) {
if (isInitialized()) {
mapInterface.getScreenLocation(latLng, callback);
}
}
public void drawCircle(LatLng latLng, int radius) {
if (isInitialized()) {
mapInterface.drawCircle(latLng, radius);
}
}
public void drawCircle(LatLng latLng, int radius, int strokeColor) {
if (isInitialized()) {
mapInterface.drawCircle(latLng, radius, strokeColor);
}
}
public void drawCircle(LatLng latLng, int radius, int strokeColor, int strokeWidth) {
if (isInitialized()) {
mapInterface.drawCircle(latLng, radius, strokeColor, strokeWidth);
}
}
public void drawCircle(LatLng latLng, int radius, int strokeColor, int strokeWidth,
int fillColor) {
if (isInitialized()) {
mapInterface.drawCircle(latLng, radius, strokeColor, strokeWidth, fillColor);
}
}
public void setPadding(int left, int top, int right, int bottom) {
if (isInitialized()) {
mapInterface.setPadding(left, top, right, bottom);
}
}
public void setOnMarkerClickListener(OnMapMarkerClickListener listener) {
onMapMarkerClickListener = listener;
}
public void setOnMarkerDragListener(OnMapMarkerDragListener listener) {
onMapMarkerDragListener = listener;
}
public void setOnMapClickListener(OnMapClickListener listener) {
onMapClickListener = listener;
}
public void setInfoWindowAdapter(GoogleMap.InfoWindowAdapter adapter, InfoWindowCreator creator) {
if (isInitialized()) {
mapInterface.setInfoWindowCreator(adapter, creator);
}
}
public void setOnInfoWindowClickListener(OnInfoWindowClickListener listener) {
onInfoWindowClickListener = listener;
}
public void clearMarkers() {
if (isInitialized()) {
mapInterface.clearMarkers();
}
}
public <T> boolean addPolyline(AirMapPolyline<T> polyline) {
if (isInitialized()) {
mapInterface.addPolyline(polyline);
return true;
}
return false;
}
public void setMapType(MapType mapType) {
mapInterface.setMapType(mapType);
}
public <T> boolean removePolyline(AirMapPolyline<T> polyline) {
if (isInitialized()) {
mapInterface.removePolyline(polyline);
return true;
}
return false;
}
public <T> boolean addPolygon(AirMapPolygon<T> polygon) {
if (isInitialized()) {
mapInterface.addPolygon(polygon);
return true;
}
return false;
}
public <T> boolean removePolygon(AirMapPolygon<T> polygon) {
if (isInitialized()) {
mapInterface.removePolygon(polygon);
return true;
}
return false;
}
public void setGeoJsonLayer(AirMapGeoJsonLayer layer) throws JSONException {
if (!isInitialized()) {
return;
}
mapInterface.setGeoJsonLayer(layer);
}
public void clearGeoJsonLayer() {
if (!isInitialized()) {
return;
}
mapInterface.clearGeoJsonLayer();
}
public boolean isInitialized() {
return mapInterface != null && mapInterface.isInitialized();
}
public boolean addMarker(AirMapMarker<?> marker) {
if (isInitialized()) {
mapInterface.addMarker(marker);
return true;
}
return false;
}
public boolean removeMarker(AirMapMarker<?> marker) {
if (isInitialized()) {
mapInterface.removeMarker(marker);
return true;
}
return false;
}
public boolean moveMarker(AirMapMarker<?> marker, LatLng to) {
if (isInitialized()) {
mapInterface.moveMarker(marker, to);
return true;
}
return false;
}
public void setMyLocationEnabled(boolean trackUserLocation) {
mapInterface.setMyLocationEnabled(trackUserLocation);
}
@Override public void onCameraChanged(LatLng latLng, int zoom) {
if (onCameraChangeListener != null) {
onCameraChangeListener.onCameraChanged(latLng, zoom);
}
}
@Override public void onMapClick(LatLng latLng) {
if (onMapClickListener != null) {
onMapClickListener.onMapClick(latLng);
}
}
@Override public void onMapMarkerClick(AirMapMarker<?> airMarker) {
if (onMapMarkerClickListener != null) {
onMapMarkerClickListener.onMapMarkerClick(airMarker);
}
}
@Override public void onMapMarkerDragStart(Marker marker) {
if (onMapMarkerDragListener != null) {
onMapMarkerDragListener.onMapMarkerDragStart(marker);
}
}
@Override public void onMapMarkerDrag(Marker marker) {
if (onMapMarkerDragListener != null) {
onMapMarkerDragListener.onMapMarkerDrag(marker);
}
}
@Override public void onMapMarkerDragEnd(Marker marker) {
if (onMapMarkerDragListener != null) {
onMapMarkerDragListener.onMapMarkerDragEnd(marker);
}
}
@Override public void onMapMarkerDragStart(long id, LatLng latLng) {
if (onMapMarkerDragListener != null) {
onMapMarkerDragListener.onMapMarkerDragStart(id, latLng);
}
}
@Override public void onMapMarkerDrag(long id, LatLng latLng) {
if (onMapMarkerDragListener != null) {
onMapMarkerDragListener.onMapMarkerDrag(id, latLng);
}
}
@Override public void onMapMarkerDragEnd(long id, LatLng latLng) {
if (onMapMarkerDragListener != null) {
onMapMarkerDragListener.onMapMarkerDragEnd(id, latLng);
}
}
@Override public void onMapLoaded() {
if (isInitialized()) {
mapInterface.setOnCameraChangeListener(this);
mapInterface.setOnMapClickListener(this);
mapInterface.setOnMarkerClickListener(this);
mapInterface.setOnMarkerDragListener(this);
mapInterface.setOnInfoWindowClickListener(this);
if (onMapInitializedListener != null) {
// only send map Initialized callback if map initialized successfully
// initialization can fail if the map leaves the screen before it loads
onMapInitializedListener.onMapInitialized();
}
}
}
@Override public void onInfoWindowClick(AirMapMarker<?> airMarker) {
if (onInfoWindowClickListener != null) {
onInfoWindowClickListener.onInfoWindowClick(airMarker);
}
}
}