diff --git a/android/API.md b/android/API.md index bfa3f7f..56b8db7 100644 --- a/android/API.md +++ b/android/API.md @@ -27,6 +27,8 @@ | `onRegionChange` | `{latitude: 0, longitude: 0, zoom: 0}` | Fired when the map is panning or zooming. | `getCenterCoordinateZoomLevel` | `mapViewRef`, `callback` | Gets the current center location and zoom level. Returns a single callback object. | | `getDirection` | `mapViewRef`, `callback` | Gets the current direction. Returns a single callback object. | +| `onOpenAnnotation` | `{title: null, subtitle: null, latitude: 0, longitude: 0}` | Fired when focusing a an annotation. If the annotation is opened already, the event will not fire. +| `onLongPress` | `{latitude: 0, longitude: 0}` | Fired when the user taps and holds the map. ## Methods for Modifying the Map State diff --git a/android/build.gradle b/android/build.gradle index 4fc3e0d..cc5f31d 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -30,7 +30,7 @@ repositories { } dependencies { - compile 'com.facebook.react:react-native:0.14.+' + compile 'com.facebook.react:react-native:0.17.+' compile('com.mapbox.mapboxsdk:mapbox-android-sdk:2.3.0@aar') { transitive = true } diff --git a/android/example.js b/android/example.js index 5eac72b..50cb926 100644 --- a/android/example.js +++ b/android/example.js @@ -55,19 +55,25 @@ var MapExample = React.createClass({ onUserLocationChange(location) { console.log(location); }, + onLongPress(location) { + console.log(location); + }, + onOpenAnnotation(annotation) { + console.log(annotation); + }, render() { return ( - this.setDirectionAnimated(mapRef, 0)}> + this.setDirectionAnimated(mapRef, 0)}> Set direction to 0 - this.setCenterCoordinateAnimated(mapRef, 40.68454331694491, -73.93592834472656)}> + this.setCenterCoordinateAnimated(mapRef, 40.68454331694491, -73.93592834472656)}> Go to New York at current zoom level - this.setCenterCoordinateZoomLevelAnimated(mapRef, 35.68829, 139.77492, 14)}> + this.setCenterCoordinateZoomLevelAnimated(mapRef, 35.68829, 139.77492, 14)}> Go to Tokyo at fixed zoom level 14 - this.addAnnotations(mapRef, [{ + this.addAnnotations(mapRef, [{ coordinates: [40.73312,-73.989], type: 'point', title: 'This is a new marker', @@ -78,29 +84,29 @@ var MapExample = React.createClass({ }])}> Add new marker - this.setUserTrackingMode(mapRef, this.userTrackingMode.follow)}> + this.setUserTrackingMode(mapRef, this.userTrackingMode.follow)}> Set userTrackingMode to follow - this.removeAllAnnotations(mapRef)}> + this.removeAllAnnotations(mapRef)}> Remove all annotations - this.setTilt(mapRef, 50)}> + this.setTilt(mapRef, 50)}> Set tilt to 50 - this.setVisibleCoordinateBoundsAnimated(mapRef, 40.712, -74.227, 40.774, -74.125, 100, 100, 100, 100)}> + this.setVisibleCoordinateBoundsAnimated(mapRef, 40.712, -74.227, 40.774, -74.125, 100, 100, 100, 100)}> Set visible bounds to 40.7, -74.2, 40.7, -74.1 - { - this.getDirection(mapRef, (direction)=>{ + { + this.getDirection(mapRef, (direction) => { console.log(direction); - }) + }); }}> Get direction - { - this.getCenterCoordinateZoomLevel(mapRef, (location)=>{ + { + this.getCenterCoordinateZoomLevel(mapRef, (location) => { console.log(location); - }) + }); }}> Get location @@ -114,7 +120,7 @@ var MapExample = React.createClass({ onRegionChange={this.onRegionChange} rotateEnabled={true} scrollEnabled={true} - style={styles.map} + style={styles.container} showsUserLocation={true} styleUrl={this.mapStyles.emerald} userTrackingMode={this.userTrackingMode.none} @@ -122,6 +128,8 @@ var MapExample = React.createClass({ zoomLevel={10} compassIsHidden={true} onUserLocationChange={this.onUserLocationChange} + onLongPress={this.onLongPress} + onOpenAnnotation={this.onOpenAnnotation} /> ); @@ -131,13 +139,6 @@ var MapExample = React.createClass({ var styles = StyleSheet.create({ container: { flex: 1 - }, - text: { - padding: 3, - marginLeft: 5 - }, - map: { - flex: 1 } }); diff --git a/android/src/main/java/com/mapbox/reactnativemapboxgl/ReactNativeMapboxGLManager.java b/android/src/main/java/com/mapbox/reactnativemapboxgl/ReactNativeMapboxGLManager.java index 367d4fe..29dacc2 100644 --- a/android/src/main/java/com/mapbox/reactnativemapboxgl/ReactNativeMapboxGLManager.java +++ b/android/src/main/java/com/mapbox/reactnativemapboxgl/ReactNativeMapboxGLManager.java @@ -13,7 +13,10 @@ import com.facebook.react.bridge.ReadableArray; import com.facebook.react.bridge.ReadableMap; import com.facebook.react.bridge.WritableMap; import com.facebook.react.uimanager.ReactProp; +import com.facebook.react.modules.core.DeviceEventManagerModule; +import com.mapbox.mapboxsdk.annotations.Marker; import com.mapbox.mapboxsdk.constants.Style; +import com.facebook.react.bridge.LifecycleEventListener; import android.graphics.RectF; import com.mapbox.mapboxsdk.geometry.CoordinateBounds; import com.facebook.react.uimanager.SimpleViewManager; @@ -52,6 +55,8 @@ public class ReactNativeMapboxGLManager extends SimpleViewManager { public static final String PROP_CENTER_COORDINATE = "centerCoordinate"; public static final String PROP_DEBUG_ACTIVE = "debugActive"; public static final String PROP_DIRECTION = "direction"; + public static final String PROP_ONOPENANNOTATION = "onOpenAnnotation"; + public static final String PROP_ONLONGPRESS = "onLongPress"; public static final String PROP_ONREGIONCHANGE = "onRegionChange"; public static final String PROP_ONUSER_LOCATION_CHANGE = "onUserLocationChange"; public static final String PROP_ROTATION_ENABLED = "rotateEnabled"; @@ -220,7 +225,9 @@ public class ReactNativeMapboxGLManager extends SimpleViewManager { location.putDouble("zoom", view.getZoomLevel()); event.putMap("src", location); ReactContext reactContext = (ReactContext) view.getContext(); - reactContext.getJSModule(RCTEventEmitter.class).receiveEvent(view.getId(), "topChange", event); + reactContext + .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class) + .emit("onRegionChange", event); } } }); @@ -242,7 +249,48 @@ public class ReactNativeMapboxGLManager extends SimpleViewManager { locationMap.putString("provider", location.getProvider()); event.putMap("src", locationMap); ReactContext reactContext = (ReactContext) view.getContext(); - reactContext.getJSModule(RCTEventEmitter.class).receiveEvent(view.getId(), "topSelect", event); + reactContext + .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class) + .emit("onUserLocationChange", event); + } + }); + } + + @ReactProp(name = PROP_ONOPENANNOTATION, defaultBoolean = true) + public void onMarkerClick(final MapView view, Boolean value) { + view.setOnMarkerClickListener(new MapView.OnMarkerClickListener() { + @Override + public boolean onMarkerClick(@Nullable Marker marker) { + WritableMap event = Arguments.createMap(); + WritableMap markerObject = Arguments.createMap(); + markerObject.putString("title", marker.getTitle()); + markerObject.putString("subtitle", marker.getSnippet()); + markerObject.putDouble("latitude", marker.getPosition().getLatitude()); + markerObject.putDouble("longitude", marker.getPosition().getLongitude()); + event.putMap("src", markerObject); + ReactContext reactContext = (ReactContext) view.getContext(); + reactContext + .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class) + .emit("onOpenAnnotation", event); + return false; + } + }); + } + + @ReactProp(name = PROP_ONLONGPRESS, defaultBoolean = true) + public void onMapLongClick(final MapView view, Boolean value) { + view.setOnMapLongClickListener(new MapView.OnMapLongClickListener() { + @Override + public void onMapLongClick(@Nullable LatLng location) { + WritableMap event = Arguments.createMap(); + WritableMap loc = Arguments.createMap(); + loc.putDouble("latitude", view.getCenterCoordinate().getLatitude()); + loc.putDouble("longitude", view.getCenterCoordinate().getLongitude()); + event.putMap("src", loc); + ReactContext reactContext = (ReactContext) view.getContext(); + reactContext + .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class) + .emit("onLongPress", event); } }); } diff --git a/index.android.js b/index.android.js index cc9df30..5748c16 100644 --- a/index.android.js +++ b/index.android.js @@ -1,7 +1,8 @@ 'use strict' var React = require('react-native'); -var { NativeModules, requireNativeComponent } = React; +var { NativeModules, requireNativeComponent, DeviceEventEmitter } = React; +var Subscribable = require('Subscribable'); var MapMixins = { setDirectionAnimated(mapRef, heading) { @@ -79,6 +80,8 @@ var ReactMapView = requireNativeComponent('RCTMapbox', { tilt: React.PropTypes.number, compassIsHidden: React.PropTypes.bool, onRegionChange: React.PropTypes.func, + onOpenAnnotation: React.PropTypes.func, + onLongPress: React.PropTypes.func, onUserLocationChange: React.PropTypes.func, // Fix for https://github.com/mapbox/react-native-mapbox-gl/issues/118 scaleY: React.PropTypes.number, @@ -117,25 +120,38 @@ var ReactMapView = requireNativeComponent('RCTMapbox', { }); var ReactMapViewWrapper = React.createClass({ + mixins: [Subscribable.Mixin], statics: { Mixin: MapMixins }, propTypes: { onRegionChange: React.PropTypes.func, - onUserLocationChange: React.PropTypes.func + onUserLocationChange: React.PropTypes.func, + onOpenAnnotation: React.PropTypes.func, + onLongPress: React.PropTypes.func + }, + componentWillMount: function() { + this.addListenerOn(DeviceEventEmitter,'onRegionChange', this.handleOnChange); + this.addListenerOn(DeviceEventEmitter,'onUserLocationChange', this.handleUserLocation); + this.addListenerOn(DeviceEventEmitter,'onOpenAnnotation', this.handleOnOpenAnnotation); + this.addListenerOn(DeviceEventEmitter,'onLongPress', this.handleOnLongPress); }, handleOnChange(event) { - if (this.props.onRegionChange) this.props.onRegionChange(event.nativeEvent.src); + if (this.props.onRegionChange) this.props.onRegionChange(event); }, handleUserLocation(event) { - if (this.props.onUserLocationChange) this.props.onUserLocationChange(event.nativeEvent.src); + if (this.props.onUserLocationChange) this.props.onUserLocationChange(event); + }, + handleOnOpenAnnotation(event) { + if (this.props.onOpenAnnotation) this.props.onOpenAnnotation(event); + }, + handleOnLongPress(event) { + if (this.props.onLongPress) this.props.onLongPress(event); }, render() { return ( + {...this.props} /> ); } });