mirror of
https://github.com/status-im/react-native-mapbox-gl.git
synced 2026-08-31 04:51:15 +00:00
Backport Android events
This commit is contained in:
@@ -1,11 +1,22 @@
|
||||
package com.mapbox.reactnativemapboxgl;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.PointF;
|
||||
import android.location.Location;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.UiThread;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.RelativeLayout;
|
||||
|
||||
import com.facebook.react.bridge.Arguments;
|
||||
import com.facebook.react.bridge.JSApplicationIllegalArgumentException;
|
||||
import com.facebook.react.bridge.LifecycleEventListener;
|
||||
import com.facebook.react.bridge.ReactContext;
|
||||
import com.facebook.react.bridge.WritableArray;
|
||||
import com.facebook.react.bridge.WritableMap;
|
||||
import com.facebook.react.common.MapBuilder;
|
||||
import com.facebook.react.common.ReactConstants;
|
||||
import com.facebook.react.uimanager.events.RCTEventEmitter;
|
||||
import com.mapbox.mapboxsdk.camera.CameraPosition;
|
||||
import com.mapbox.mapboxsdk.camera.CameraUpdate;
|
||||
import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
|
||||
@@ -18,10 +29,17 @@ import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
|
||||
import com.mapbox.mapboxsdk.maps.UiSettings;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.logging.Handler;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class ReactNativeMapboxGLView extends LinearLayout implements OnMapReadyCallback, LifecycleEventListener {
|
||||
public class ReactNativeMapboxGLView extends RelativeLayout implements
|
||||
OnMapReadyCallback, LifecycleEventListener,
|
||||
MapboxMap.OnMapClickListener, MapboxMap.OnMapLongClickListener,
|
||||
MapboxMap.OnMyBearingTrackingModeChangeListener, MapboxMap.OnMyLocationTrackingModeChangeListener,
|
||||
MapboxMap.OnMyLocationChangeListener,
|
||||
MapView.OnMapChangedListener
|
||||
{
|
||||
|
||||
private MapboxMap _map = null;
|
||||
private MapView _mapView = null;
|
||||
@@ -32,14 +50,19 @@ public class ReactNativeMapboxGLView extends LinearLayout implements OnMapReadyC
|
||||
private MapboxMapOptions _mapOptions;
|
||||
private int _locationTrackingMode;
|
||||
private int _bearingTrackingMode;
|
||||
private boolean _trackingModeUpdateScheduled = false;
|
||||
private boolean _showsUserLocation;
|
||||
private boolean _zoomEnabled = true;
|
||||
private boolean _scrollEnabled = true;
|
||||
private boolean _rotateEnabled = true;
|
||||
private int _paddingTop, _paddingRight, _paddingBottom, _paddingLeft;
|
||||
|
||||
private android.os.Handler _trackingModeHandler;
|
||||
|
||||
@UiThread
|
||||
public ReactNativeMapboxGLView(Context context, ReactNativeMapboxGLManager manager) {
|
||||
super(context);
|
||||
_trackingModeHandler = new android.os.Handler();
|
||||
_manager = manager;
|
||||
_mapOptions = MapboxMapOptions.createFromAttributes(context, null);
|
||||
_mapOptions.zoomGesturesEnabled(true);
|
||||
@@ -56,7 +79,6 @@ public class ReactNativeMapboxGLView extends LinearLayout implements OnMapReadyC
|
||||
if (_mapView == null) {
|
||||
setupMapView();
|
||||
}
|
||||
_mapView.onCreate(null);
|
||||
_paused = false;
|
||||
_mapView.onResume();
|
||||
_manager.getContext().addLifecycleEventListener(this);
|
||||
@@ -89,9 +111,17 @@ public class ReactNativeMapboxGLView extends LinearLayout implements OnMapReadyC
|
||||
|
||||
@Override
|
||||
public void onHostDestroy() {
|
||||
_mapView.removeOnMapChangedListener(this);
|
||||
if (_map != null) {
|
||||
_map.setOnMapClickListener(null);
|
||||
_map.setOnMapLongClickListener(null);
|
||||
_map.setOnMyLocationTrackingModeChangeListener(null);
|
||||
_map.setOnMyBearingTrackingModeChangeListener(null);
|
||||
_map.setOnMyLocationChangeListener(null);
|
||||
_map = null;
|
||||
}
|
||||
_mapView.onDestroy();
|
||||
_mapView = null;
|
||||
_map = null;
|
||||
}
|
||||
|
||||
// Initialization
|
||||
@@ -99,13 +129,17 @@ public class ReactNativeMapboxGLView extends LinearLayout implements OnMapReadyC
|
||||
private void setupMapView() {
|
||||
_mapOptions.camera(_initialCamera.build());
|
||||
_mapView = new MapView(this.getContext(), _mapOptions);
|
||||
_mapView.getMapAsync(this);
|
||||
this.addView(_mapView);
|
||||
_mapView.addOnMapChangedListener(this);
|
||||
_mapView.onCreate(null);
|
||||
_mapView.getMapAsync(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMapReady(MapboxMap mapboxMap) {
|
||||
_map = mapboxMap;
|
||||
|
||||
// Configure map
|
||||
_map.setMyLocationEnabled(_showsUserLocation);
|
||||
_map.getTrackingSettings().setMyLocationTrackingMode(_locationTrackingMode);
|
||||
_map.getTrackingSettings().setMyBearingTrackingMode(_bearingTrackingMode);
|
||||
@@ -132,6 +166,13 @@ public class ReactNativeMapboxGLView extends LinearLayout implements OnMapReadyC
|
||||
if (uiSettings.isCompassEnabled() != _mapOptions.getCompassEnabled()) {
|
||||
uiSettings.setCompassEnabled(_mapOptions.getCompassEnabled());
|
||||
}
|
||||
|
||||
// Attach listeners
|
||||
_map.setOnMapClickListener(this);
|
||||
_map.setOnMapLongClickListener(this);
|
||||
_map.setOnMyLocationTrackingModeChangeListener(this);
|
||||
_map.setOnMyBearingTrackingModeChangeListener(this);
|
||||
_map.setOnMyLocationChangeListener(this);
|
||||
}
|
||||
|
||||
// Props
|
||||
@@ -238,6 +279,151 @@ public class ReactNativeMapboxGLView extends LinearLayout implements OnMapReadyC
|
||||
if (_map != null) { _map.setPadding(left, top, right, bottom); }
|
||||
}
|
||||
|
||||
// Events
|
||||
|
||||
void emitEvent(String name, @Nullable WritableMap event) {
|
||||
if (event == null) {
|
||||
event = Arguments.createMap();
|
||||
}
|
||||
event.putString("name", name);
|
||||
((ReactContext)getContext())
|
||||
.getJSModule(RCTEventEmitter.class)
|
||||
.receiveEvent(getId(), "topChange", event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMapClick(LatLng point) {
|
||||
PointF screenCoords = _map.getProjection().toScreenLocation(point);
|
||||
|
||||
WritableMap event = Arguments.createMap();
|
||||
WritableMap src = Arguments.createMap();
|
||||
src.putDouble("latitude", point.getLatitude());
|
||||
src.putDouble("longitude", point.getLongitude());
|
||||
src.putDouble("screenCoordX", screenCoords.x);
|
||||
src.putDouble("screenCoordY", screenCoords.y);
|
||||
event.putMap("src", src);
|
||||
|
||||
emitEvent("onTap", event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMapLongClick(@NonNull LatLng point) {
|
||||
PointF screenCoords = _map.getProjection().toScreenLocation(point);
|
||||
|
||||
WritableMap event = Arguments.createMap();
|
||||
WritableMap src = Arguments.createMap();
|
||||
src.putDouble("latitude", point.getLatitude());
|
||||
src.putDouble("longitude", point.getLongitude());
|
||||
src.putDouble("screenCoordX", screenCoords.x);
|
||||
src.putDouble("screenCoordY", screenCoords.y);
|
||||
event.putMap("src", src);
|
||||
|
||||
emitEvent("onLongPress", event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMyLocationChange(@Nullable Location location) {
|
||||
WritableMap event = Arguments.createMap();
|
||||
WritableMap src = Arguments.createMap();
|
||||
|
||||
if (location == null) {
|
||||
src.putString("message", "Could not get user location");
|
||||
event.putMap("src", src);
|
||||
emitEvent("onLocateUserFailed", event);
|
||||
return;
|
||||
}
|
||||
|
||||
src.putDouble("latitude", location.getLatitude());
|
||||
src.putDouble("longitude", location.getLongitude());
|
||||
src.putDouble("magneticHeading", location.getBearing());
|
||||
src.putDouble("trueHeading", location.getBearing());
|
||||
src.putDouble("headingAccuracy", 10.0);
|
||||
src.putBoolean("isUpdating", true);
|
||||
event.putMap("src", src);
|
||||
emitEvent("onUpdateUserLocation", event);
|
||||
}
|
||||
|
||||
class TrackingModeChangeRunnable implements Runnable {
|
||||
ReactNativeMapboxGLView target;
|
||||
TrackingModeChangeRunnable(ReactNativeMapboxGLView target) {
|
||||
this.target = target;
|
||||
}
|
||||
@Override
|
||||
public void run() {
|
||||
target.onTrackingModeChange();
|
||||
}
|
||||
}
|
||||
|
||||
public void onTrackingModeChange() {
|
||||
if (!_trackingModeUpdateScheduled) { return; }
|
||||
_trackingModeUpdateScheduled = false;
|
||||
|
||||
for (int mode = 0; mode < ReactNativeMapboxGLModule.locationTrackingModes.length; mode++) {
|
||||
if (_locationTrackingMode == ReactNativeMapboxGLModule.locationTrackingModes[mode] &&
|
||||
_bearingTrackingMode == ReactNativeMapboxGLModule.bearingTrackingModes[mode]) {
|
||||
WritableMap event = Arguments.createMap();
|
||||
event.putInt("src", mode);
|
||||
emitEvent("onChangeUserTrackingMode", event);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@UiThread
|
||||
public void onMyBearingTrackingModeChange(int myBearingTrackingMode) {
|
||||
if (_bearingTrackingMode == myBearingTrackingMode) { return; }
|
||||
_bearingTrackingMode = myBearingTrackingMode;
|
||||
_trackingModeUpdateScheduled = true;
|
||||
_trackingModeHandler.post(new TrackingModeChangeRunnable(this));
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@UiThread
|
||||
public void onMyLocationTrackingModeChange(int myLocationTrackingMode) {
|
||||
if (_locationTrackingMode == myLocationTrackingMode) { return; }
|
||||
_locationTrackingMode = myLocationTrackingMode;
|
||||
_trackingModeUpdateScheduled = true;
|
||||
_trackingModeHandler.post(new TrackingModeChangeRunnable(this));
|
||||
}
|
||||
|
||||
WritableMap serializeCurrentRegion() {
|
||||
CameraPosition camera = _map == null
|
||||
? _initialCamera.build()
|
||||
: _map.getCameraPosition();
|
||||
|
||||
WritableMap event = Arguments.createMap();
|
||||
WritableMap src = Arguments.createMap();
|
||||
src.putDouble("longitude", camera.target.getLongitude());
|
||||
src.putDouble("latitude", camera.target.getLatitude());
|
||||
src.putDouble("zoomLevel", camera.zoom);
|
||||
src.putDouble("direction", camera.bearing);
|
||||
src.putDouble("pitch", camera.tilt);
|
||||
event.putMap("src", src);
|
||||
return event;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMapChanged(int change) {
|
||||
switch (change) {
|
||||
case MapView.REGION_WILL_CHANGE:
|
||||
case MapView.REGION_WILL_CHANGE_ANIMATED:
|
||||
emitEvent("onRegionWillChange", serializeCurrentRegion()); // TODO: These should be throttled
|
||||
break;
|
||||
case MapView.REGION_DID_CHANGE:
|
||||
case MapView.REGION_DID_CHANGE_ANIMATED:
|
||||
emitEvent("onRegionChange", serializeCurrentRegion());
|
||||
break;
|
||||
case MapView.WILL_START_LOADING_MAP:
|
||||
emitEvent("onStartLoadingMap", null);
|
||||
break;
|
||||
case MapView.DID_FINISH_LOADING_MAP:
|
||||
emitEvent("onFinishLoadingMap", null);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Getters
|
||||
|
||||
public CameraPosition getCameraPosition() {
|
||||
|
||||
Reference in New Issue
Block a user