react native android 高德地圖原生代碼編寫
- react native android 高德地圖原生代碼編寫
- android代碼
- MyAmapView
- 高德地圖注意事項
- 代碼
- AMapViewManager
- 代碼注解
- viewManager如何被外部的js調用的
- error
- 代碼
- AMapModule
- 代碼注解
- 代碼
- AMapPackage
- MainApplication
- MyAmapView
- js代碼
- android代碼
android代碼
MyAmapView
高德地圖注意事項
-
key授權失敗
請注意包含高德key的meta-data标簽是否被包含在application标簽中
- 高德地圖無法顯示
- 先檢視一下rn中地圖view是否占了位置沒有顯示,設定rn中的view的背景顔色可檢視,rnview的大小設定沒.如果占了位置,檢查是否調用
mapView.onCreate();
- 使用frameLayout請檢查是否調用
this.addView()
- 先檢視一下rn中地圖view是否占了位置沒有顯示,設定rn中的view的背景顔色可檢視,rnview的大小設定沒.如果占了位置,檢查是否調用
- 以下就是部分代碼
代碼
因為公司原因,貼出部分代碼,有需要的可以直接從裡面拷貝一些代碼來用
package com.aiyunbao.aMap;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.location.Location;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import com.aiyunbao.R;
import com.aiyunbao.marker.MarkerUtil;
import com.aiyunbao.poi.PoiSearchBiz;
import com.aiyunbao.utils.SensorEventHelper;
import com.amap.api.location.AMapLocationClient;
import com.amap.api.location.AMapLocationClientOption;
import com.amap.api.maps.AMap;
import com.amap.api.maps.CameraUpdate;
import com.amap.api.maps.LocationSource;
import com.amap.api.maps.MapView;
import com.amap.api.maps.UiSettings;
import com.amap.api.maps.model.BitmapDescriptor;
import com.amap.api.maps.model.BitmapDescriptorFactory;
import com.amap.api.maps.model.CameraPosition;
import com.amap.api.maps.model.Circle;
import com.amap.api.maps.model.CircleOptions;
import com.amap.api.maps.model.LatLng;
import com.amap.api.maps.model.Marker;
import com.amap.api.maps.model.MarkerOptions;
import com.amap.api.maps.model.MyLocationStyle;
import com.amap.api.services.core.LatLonPoint;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.uimanager.ThemedReactContext;
import static com.amap.api.maps.AMapOptions.LOGO_POSITION_BOTTOM_RIGHT;
import static com.amap.api.maps.AMapOptions.ZOOM_POSITION_RIGHT_BUTTOM;
/**
* Created by aiyun-pc1 on 2017/5/8.
*/
public class MyAMapView extends FrameLayout implements AMap.OnMyLocationChangeListener, AMap.OnMapClickListener,
AMap.OnMapLongClickListener, AMap.OnCameraChangeListener, AMap.OnMarkerClickListener,
AMap.OnMarkerDragListener, AMap.OnInfoWindowClickListener, AMap.InfoWindowAdapter, LocationSource {
private final ThemedReactContext reactContext;
private final ViewGroup.LayoutParams PARAM;
private MapView MAPVIEW;
private AMap aMap;
private UiSettings mUiSettings;
public AMapLocationClientOption mLocationOption = null;
private AMapLocationClient mlocationClient;
private long startTime;
private OnLocationChangedListener mListener;
private boolean mFirstFix = false;
private static final int STROKE_COLOR = Color.argb(, , , );
private static final int FILL_COLOR = Color.argb(, , , );
/**
* 傳感器
*/
private SensorEventHelper mSensorHelper;
private Marker mLocMarker;
private Circle mCircle;
/**
* 螢幕中心點的大頭針
*/
private Marker screenPosition;
public MyAMapView(ThemedReactContext reactContext) {
super(reactContext);
this.reactContext = reactContext;
PARAM = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
init();
}
public AMap getAmap() {
if (aMap == null) {
aMap = MAPVIEW.getMap();
}
return aMap;
}
/**
* 初始化控件,定位位置
*/
private void init() {
//定位箭頭旋轉
mSensorHelper = new SensorEventHelper(reactContext);
if (mSensorHelper != null) {
mSensorHelper.registerSensorListener();
}
MAPVIEW = new MapView(reactContext);
MAPVIEW.setLayoutParams(PARAM);
this.addView(MAPVIEW);
MAPVIEW.onCreate(reactContext.getCurrentActivity().getIntent().getExtras());
setUpMap();
}
/**
* 設定一些amap的屬性
*/
private void setUpMap() {
aMap = MAPVIEW.getMap();
aMap.setMapType(AMap.MAP_TYPE_NORMAL);// 矢量地圖模式
//控件互動
mUiSettings = aMap.getUiSettings();//執行個體化UiSettings類
mUiSettings.setZoomControlsEnabled(false);//顯示縮放按鈕
//縮放按鈕 右邊界中部:ZOOM_POSITION_RIGHT_CENTER 右下:ZOOM_POSITION_RIGHT_BUTTOM。
mUiSettings.setZoomPosition(ZOOM_POSITION_RIGHT_BUTTOM);
//Logo的位置 左下:LOGO_POSITION_BOTTOM_LEFT 底部居中:LOGO_POSITION_BOTTOM_CENTER 右下:LOGO_POSITION_BOTTOM_RIGHT
mUiSettings.setLogoPosition(LOGO_POSITION_BOTTOM_RIGHT);
mUiSettings.setCompassEnabled(false);//指南針
mUiSettings.setZoomGesturesEnabled(true);//手勢縮放
mUiSettings.setScaleControlsEnabled(true);//比例尺
// changeCamera(
// CameraUpdateFactory.newCameraPosition(new CameraPosition(
// latLng, ZOOMLEVEL, 30, 0)));//建立view時候傳入之前定位到目前坐标位置把地圖中心移動過去
// addLocationMarker(latLng, RADIUS, mLocMarker);
initBluePoint();
initListener();
screenPosition = MarkerUtil.addMarkerInScreenCenter(aMap, "purple_pin", reactContext);
}
private void initListener() {
aMap.setOnMapClickListener(this);// 對amap添加單擊地圖事件監聽器
aMap.setOnMapLongClickListener(this);// 對amap添加長按地圖事件監聽器
aMap.setOnCameraChangeListener(this);// 對amap添加移動地圖事件監聽器
aMap.setOnMarkerClickListener(this);// marker點選事件監聽器
aMap.setOnMarkerDragListener(this);// 設定marker可拖拽事件監聽器
// aMap.setOnMapLoadedListener(this);// 設定amap加載成功事件監聽器
aMap.setOnMarkerClickListener(this);// 設定點選marker事件監聽器
aMap.setOnInfoWindowClickListener(this);// 設定點選infoWindow事件監聽器
aMap.setInfoWindowAdapter(this);// 設定自定義InfoWindow樣式
aMap.setOnMyLocationChangeListener(this);//設定SDK 自帶定位消息監聽
}
/**
* Activity onResume後調用view的onAttachedToWindow
*/
@Override
protected void onAttachedToWindow() {
// init();
super.onAttachedToWindow();
}
/**
* view生命周期onDetachedFromWindow
*/
@Override
protected void onDetachedFromWindow() {
this.removeView(MAPVIEW);
MAPVIEW.onDestroy();
super.onDetachedFromWindow();
}
/**
* 對應onResume、對應onPause
*
* @param hasWindowFocus
*/
@Override
public void onWindowFocusChanged(boolean hasWindowFocus) {
super.onWindowFocusChanged(hasWindowFocus);
if (hasWindowFocus) {
// 對應onResume
MAPVIEW.onResume();
} else {
//對應onPause
MAPVIEW.onPause();
}
}
/**
* 定位到裝置定位位置
*/
public void startLocation() {
startTime = System.currentTimeMillis();
Log.i("Test", "startTime:" + startTime);
if (mlocationClient == null) {
Log.i("Test", "mlocationClient = null");
mlocationClient = new AMapLocationClient(reactContext);
mLocationOption = new AMapLocationClientOption();
//設定定位監聽
// mlocationClient.setLocationListener(this);
//設定為高精度定位模式
mLocationOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);
mLocationOption.setOnceLocation(true);
// mLocationOption.setOnceLocationLatest(true);
mLocationOption.setLocationCacheEnable(true);//定位緩存政策
// mLocationOption.setInterval(10);
// mLocationOption.setInterval(3*60*1000);
//設定定位參數
mlocationClient.setLocationOption(mLocationOption);
// 此方法為每隔固定時間會發起一次定位請求,為了減少電量消耗或網絡流量消耗,
// 注意設定合适的定位時間的間隔(最小間隔支援為2000ms),并且在合适時間調用stopLocation()方法來取消定位請求
// 在定位結束後,在合适的生命周期調用onDestroy()方法
// 在單次定位情況下,定位無論成功與否,都無需調用stopLocation()方法移除請求,定位sdk内部會移除
}
mlocationClient.startLocation();
}
/**
* 激活定位
*/
@Override
public void activate(OnLocationChangedListener listener) {
mListener = listener;
if (mlocationClient == null) {
mlocationClient = new AMapLocationClient(reactContext);
mLocationOption = new AMapLocationClientOption();
//設定定位監聽
// mlocationClient.setLocationListener(this);
//設定為高精度定位模式
mLocationOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);
//設定定位參數
mlocationClient.setLocationOption(mLocationOption);
// 此方法為每隔固定時間會發起一次定位請求,為了減少電量消耗或網絡流量消耗,
// 注意設定合适的定位時間的間隔(最小間隔支援為2000ms),并且在合适時間調用stopLocation()方法來取消定位請求
// 在定位結束後,在合适的生命周期調用onDestroy()方法
// 在單次定位情況下,定位無論成功與否,都無需調用stopLocation()方法移除請求,定位sdk内部會移除
mlocationClient.startLocation();
}
}
/**
* 停止定位
*/
@Override
public void deactivate() {
mListener = null;
if (mlocationClient != null) {
mlocationClient.stopLocation();
mlocationClient.onDestroy();
}
mlocationClient = null;
}
// @Override
// public void onLocationChanged(AMapLocation amapLocation) {
// if (amapLocation != null) {
// if (amapLocation.getErrorCode() == 0) {
// //定位成功回調資訊,設定相關消息
// amapLocation.getLocationType();//擷取目前定位結果來源,如網絡定位結果,詳見定位類型表
// amapLocation.getLatitude();//擷取緯度
// amapLocation.getLongitude();//擷取經度
// amapLocation.getAccuracy();//擷取精度資訊
// SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
// Date date = new Date(amapLocation.getTime());
// df.format(date);//定位時間
// mListener.onLocationChanged(amapLocation);// 顯示系統小藍點
//
// LatLng location = new LatLng(amapLocation.getLatitude(), amapLocation.getLongitude());
// if (!mFirstFix) {
// mFirstFix = true;
// addCircle(location, amapLocation.getAccuracy());//添加定位精度圓
// addMarker(location);//添加定位圖示
// mSensorHelper.setCurrentMarker(mLocMarker);//定位圖示旋轉
// } else {
// mCircle.setCenter(location);
// mCircle.setRadius(amapLocation.getAccuracy());
// mLocMarker.setPosition(location);
// }
// aMap.moveCamera(CameraUpdateFactory.newLatLngZoom(location, 18));
// } else {
// //顯示錯誤資訊ErrCode是錯誤碼,errInfo是錯誤資訊,詳見錯誤碼表。
// Log.e("定位失敗", "location Error, ErrCode:"
// + amapLocation.getErrorCode() + ", errInfo:"
// + amapLocation.getErrorInfo());
// }
// }
// }
@Override
public void onMyLocationChange(Location location) {
// 定位回調監聽
if (location != null) {
Log.e("amap", "onMyLocationChange 定位成功, lat: " + location.getLatitude() + " lon: " + location.getLongitude());
Bundle bundle = location.getExtras();
if (bundle != null) {
int errorCode = bundle.getInt(MyLocationStyle.ERROR_CODE);
String errorInfo = bundle.getString(MyLocationStyle.ERROR_INFO);
// 定位類型,可能為GPS WIFI等,具體可以參考官網的定位SDK介紹
int locationType = bundle.getInt(MyLocationStyle.LOCATION_TYPE);
/*
errorCode
errorInfo
locationType
*/
Log.e("amap", "定位資訊, code: " + errorCode + " errorInfo: " + errorInfo + " locationType: " + locationType);
} else {
Log.e("amap", "定位資訊, bundle is null ");
}
} else {
Log.e("amap", "定位失敗");
}
}
@Deprecated
private void addCircle(LatLng latlng, double radius) {
CircleOptions options = new CircleOptions();
options.strokeWidth(f);
options.fillColor(FILL_COLOR);
options.strokeColor(STROKE_COLOR);
options.center(latlng);
options.radius(radius);
mCircle = aMap.addCircle(options);
}
@Deprecated
private void addMarker(LatLng latlng) {
if (mLocMarker != null) {
return;
}
Bitmap bMap = BitmapFactory.decodeResource(this.getResources(),
R.drawable.navi_map_gps_locked);
BitmapDescriptor des = BitmapDescriptorFactory.fromBitmap(bMap);
// BitmapDescriptor des = BitmapDescriptorFactory.fromResource(R.drawable.navi_map_gps_locked);
MarkerOptions options = new MarkerOptions();
options.icon(des);
options.anchor(f, f);
options.position(latlng);
mLocMarker = aMap.addMarker(options);
mLocMarker.setTitle("我的位置");
}
/**
* 初始化定位的小藍點
*/
private void initBluePoint() {
MyLocationStyle myLocationStyle = new MyLocationStyle();//初始化定位藍點樣式類
//設定預設定位按鈕是否顯示,非必需設定。
aMap.getUiSettings().setMyLocationButtonEnabled(true);
// 設定為true表示啟動顯示定位藍點,false表示隐藏定位藍點并不進行定位,預設是false。
// 不知道為什麼它會一直回到目前位置
aMap.setMyLocationEnabled(true);
//隻定位一次。
// myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_SHOW);
//定位一次,且将視角移動到地圖中心點。
myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATE);
//連續定位、且将視角移動到地圖中心點,定位藍點跟随裝置移動。(1秒1次定位)
// myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_FOLLOW) ;
//連續定位、且将視角移動到地圖中心點,地圖依照裝置方向旋轉,定位點會跟随裝置移動。(1秒1次定位)
// myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_MAP_ROTATE);
//連續定位、且将視角移動到地圖中心點,定位點依照裝置方向旋轉,并且會跟随裝置移動。(1秒1次定位)預設執行此種模式。
// myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE);
//設定連續定位模式下的定位間隔,隻在連續定位模式下生效,單次定位模式下不會生效。機關為毫秒。
myLocationStyle.interval();
// 自定義定位藍點圖示
myLocationStyle.myLocationIcon(BitmapDescriptorFactory.
fromResource(R.drawable.gps_point));
// 自定義精度範圍的圓形邊框顔色
myLocationStyle.strokeColor(STROKE_COLOR);
//自定義精度範圍的圓形邊框寬度
myLocationStyle.strokeWidth();
// 設定圓形的填充顔色
myLocationStyle.radiusFillColor(FILL_COLOR);
// myLocationStyle.anchor(float u, float v);//設定定位藍點圖示的錨點方法。
aMap.setMyLocationStyle(myLocationStyle);//設定定位藍點的Style
}
/**
* 對單擊地圖事件回調
*/
@Override
public void onMapClick(LatLng point) {
Log.d("tapped, point", point.toString());
WritableMap event = Arguments.createMap();
event.putString("LatLng", point.toString());
}
/**
* 對長按地圖事件回調
*/
@Override
public void onMapLongClick(LatLng point) {
Log.d("long pressed, point", point.toString());
}
/**
* 對正在移動地圖事件回調
*/
@Override
public void onCameraChange(CameraPosition cameraPosition) {
Log.d("onCameraChange:", cameraPosition.toString());
//大頭針跳動動畫
MarkerUtil.startJumpAnimation(aMap, screenPosition, reactContext);
LatLonPoint lp = new LatLonPoint(cameraPosition.target.latitude, cameraPosition.target.longitude);
PoiSearchBiz poiSearchBiz = new PoiSearchBiz(reactContext, null);
poiSearchBiz.doSearchQuery("key", "", , , lp, null, null);
}
/**
* 對移動地圖結束事件回調
*/
@Override
public void onCameraChangeFinish(CameraPosition cameraPosition) {
Log.d("onCameraChangeFinish", cameraPosition.toString());
}
/**
* 根據動畫按鈕狀态,調用函數animateCamera或moveCamera來改變可視區域
*/
public void changeCamera(CameraUpdate update) {
aMap.moveCamera(update);
}
/**
* 對marker标注點點選響應事件
*/
@Override
public boolean onMarkerClick(final Marker marker) {
Log.d("marker标注點點選響應事件", marker.getTitle());
return false;
}
/**
* 監聽點選infowindow視窗事件回調
*/
@Override
public void onInfoWindowClick(Marker marker) {
Log.d("監聽點選infowindow視窗事件回調", "你點選了infoWindow視窗" + marker.getTitle());
}
/**
* 監聽拖動marker時事件回調
*/
@Override
public void onMarkerDrag(Marker marker) {
Log.d(marker.getTitle() + "拖動時目前位置", "(lat,lng)\n("
+ marker.getPosition().latitude + ","
+ marker.getPosition().longitude + ")");
}
/**
* 監聽拖動marker結束事件回調
*/
@Override
public void onMarkerDragEnd(Marker marker) {
Log.d("監聽拖動marker結束事件回調", marker.getTitle() + "停止拖動");
}
/**
* 監聽開始拖動marker事件回調
*/
@Override
public void onMarkerDragStart(Marker marker) {
Log.d("監聽開始拖動marker事件回調", "開始拖動");
}
/**
* 監聽自定義infowindow視窗的infocontents事件回調
*/
@Override
public View getInfoContents(Marker marker) {
return null;
}
/**
* 監聽自定義infowindow視窗的infowindow事件回調
*/
@Override
public View getInfoWindow(Marker marker) {
return null;
}
}
AMapViewManager
代碼注解
- 監聽view的listener
@Nullable
@Override
public Map getExportedCustomDirectEventTypeConstants() {
Map<String, Map<String, String>> map = new HashMap<>();
//mapBuilder.put("Android裡面的方法名", MapBuilder.of("registrationName", "JS端的方法名"));
//Android裡面的方法名類似于廣播的action
map.put("onMapInitialed", MapBuilder.of("registrationName", "onMapInitialed"));
return map;
}
viewManager如何被外部的js調用的
- viewManager通過Module來暴露方法
- 通過屬性的更新來調用
/**
* 設定線路規劃參數
*/
@ReactProp(name = "drivingRoutePlan")
@SuppressWarnings("unused")
public void setDrivingRoutePlan(MyAMapView myAMapView, ReadableMap drivingRoutePlan) {
try {
double latitude = drivingRoutePlan.getDouble("latitude");
double longitude = drivingRoutePlan.getDouble("longitude");
int mode = drivingRoutePlan.getInt("mode");
DriveRouteBiz driveRouteBiz = new DriveRouteBiz(reactContext, myAMapView);
driveRouteBiz.searchRouteResult(ROUTE_TYPE_DRIVE, mode, latitude, longitude);
} catch (NoSuchKeyException e) {
}
}
error
-
屬性不能更新
js代碼沒問題,請檢查被調用的android方法是否有空指針
代碼
package com.aiyunbao;
import android.support.annotation.Nullable;
import com.aiyunbao.aMap.MyAMapView;
import com.aiyunbao.route.DriveRouteBiz;
import com.amap.api.maps.CameraUpdateFactory;
import com.facebook.react.bridge.NoSuchKeyException;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.common.MapBuilder;
import com.facebook.react.uimanager.ThemedReactContext;
import com.facebook.react.uimanager.ViewGroupManager;
import com.facebook.react.uimanager.annotations.ReactProp;
import com.facebook.react.uimanager.events.RCTEventEmitter;
import java.util.HashMap;
import java.util.Map;
import static com.aiyunbao.route.DriveRouteBiz.ROUTE_TYPE_DRIVE;
import static com.amap.api.maps.AMapOptions.LOGO_POSITION_BOTTOM_CENTER;
import static com.amap.api.maps.AMapOptions.LOGO_POSITION_BOTTOM_LEFT;
import static com.amap.api.maps.AMapOptions.LOGO_POSITION_BOTTOM_RIGHT;
/**
* Created by aiyun-pc1 on 2017/5/8.
* 普通地圖view,提供定位 poi搜尋 位址轉碼 marker标記
*/
public class AMapViewManager extends ViewGroupManager<MyAMapView> {
private static ReactApplicationContext reactContext;
private Map<String, Object> constants;
public AMapViewManager(ReactApplicationContext reactContext) {
this.reactContext = reactContext;
}
@Override
public String getName() {
return "RCTAMapView";
}
@Override
protected MyAMapView createViewInstance(ThemedReactContext reactContext) {
setConstants();
MyAMapView view = new MyAMapView(reactContext);
return view;
}
public void setConstants() {
constants = new HashMap<>();
//Logo的位置
constants.put("LOGO_POSITION_BOTTOM_LEFT", LOGO_POSITION_BOTTOM_LEFT);
constants.put("LOGO_POSITION_BOTTOM_CENTER", LOGO_POSITION_BOTTOM_CENTER);
constants.put("LOGO_POSITION_BOTTOM_RIGHT", LOGO_POSITION_BOTTOM_RIGHT);
}
/**
* 是否顯示使用者目前位置(預設為開啟)
*/
@ReactProp(name = "showsUserLocation", defaultBoolean = true)
@SuppressWarnings("unused")
public void setShowsUserLocation(MyAMapView myAMapView, Boolean showsUserLocation) {
// 設定為true表示啟動顯示定位藍點,false表示隐藏定位藍點并不進行定位,
myAMapView.getAmap().setMyLocationEnabled(showsUserLocation);
}
//
// @ReactProp(name = "userLocationRepresentation", defaultBoolean = true)
// @SuppressWarnings("unused")
// public void setUserLocationRepresentation(MyAMapView myAMapView, Boolean userLocationRepresentation) {
//
// }
/**
* 跟随模式
*/
@ReactProp(name = "userTrackingMode", defaultBoolean = true)
@SuppressWarnings("unused")
public void setUserTrackingMode(MyAMapView myAMapView, Boolean userTrackingMode) {
}
/**
* logo
* //Logo的位置
* 左下:LOGO_POSITION_BOTTOM_LEFT
* 底部居中:LOGO_POSITION_BOTTOM_CENTER
* 右下:LOGO_POSITION_BOTTOM_RIGHT
*/
@ReactProp(name = "logoCenterAndroid")
@SuppressWarnings("unused")
public void setLog(MyAMapView myAMapView, String logoCenterAndroid) {
myAMapView.getAmap().getUiSettings().setLogoPosition((Integer) constants.get(logoCenterAndroid));
}
/**
* 比例尺
*/
@ReactProp(name = "showsScale")
@SuppressWarnings("unused")
public void setShowsScale(final MyAMapView myAMapView, final Boolean showsScale) {
//控制比例尺控件是否顯示
myAMapView.getAmap().getUiSettings().setScaleControlsEnabled(showsScale);
}
/**
* 縮放手勢
*/
@ReactProp(name = "zoomEnabled", defaultBoolean = true)
@SuppressWarnings("unused")
public void setZoomEnabled(MyAMapView myAMapView, Boolean zoomEnabled) {
myAMapView.getAmap().getUiSettings().setZoomGesturesEnabled(zoomEnabled);
}
/**
* 滑動手勢
*/
@ReactProp(name = "scrollEnabled", defaultBoolean = true)
@SuppressWarnings("unused")
public void setScrollEnabled(MyAMapView myAMapView, Boolean scrollEnabled) {
myAMapView.getAmap().getUiSettings().setScrollGesturesEnabled(scrollEnabled);
}
/**
* 旋轉手勢
*/
@ReactProp(name = "rotateEnabled", defaultBoolean = true)
@SuppressWarnings("unused")
public void setRotateEnabled(MyAMapView myAMapView, Boolean rotateEnabled) {
myAMapView.getAmap().getUiSettings().setRotateGesturesEnabled(rotateEnabled);
}
/**
* 傾斜手勢
*/
@ReactProp(name = "rotateCameraEnabled", defaultBoolean = true)
@SuppressWarnings("unused")
public void setRotateCameraEnabled(MyAMapView myAMapView, Boolean rotateCameraEnabled) {
myAMapView.getAmap().getUiSettings().setTiltGesturesEnabled(rotateCameraEnabled);
}
/**
* 縮放級别
*/
@ReactProp(name = "zoomLevel")
@SuppressWarnings("unused")
public void setZoomLevel(MyAMapView myAMapView, float zoomLevel) {
myAMapView.getAmap().moveCamera(CameraUpdateFactory.zoomTo(zoomLevel));
}
/**
* 設定中心大頭針
*/
@ReactProp(name = "startAnnotation")
@SuppressWarnings("unused")
public void setStartAnnotation(MyAMapView myAMapView, ReadableMap startAnnotation) {
}
/**
*
*/
@ReactProp(name = "destinationAnnotation")
@SuppressWarnings("unused")
public void setDestinationAnnotation(MyAMapView myAMapView, ReadableMap destinationAnnotation) {
}
/**
* 設定線路規劃參數
*/
@ReactProp(name = "drivingRoutePlan")
@SuppressWarnings("unused")
public void setDrivingRoutePlan(MyAMapView myAMapView, ReadableMap drivingRoutePlan) {
try {
double latitude = drivingRoutePlan.getDouble("latitude");
double longitude = drivingRoutePlan.getDouble("longitude");
int mode = drivingRoutePlan.getInt("mode");
DriveRouteBiz driveRouteBiz = new DriveRouteBiz(reactContext, myAMapView);
driveRouteBiz.searchRouteResult(ROUTE_TYPE_DRIVE, mode, latitude, longitude);
} catch (NoSuchKeyException e) {
}
/**
* {
latitude: PropTypes.number,
longitude: PropTypes.number,
waypoints: PropTypes.arrayOf(PropTypes.shape(
)),
strategy: PropTypes.number,
startPlan: PropTypes.bool,
mode: PropTypes.number
}
*/
}
//
// context.getJSModule(RCTEventEmitter.class).receiveEvent(id, "Android裡面的方法名",map);
// 某方法(value){ alert('收到!');}
// render() {
// return (
// <View style={styles.container}>
// <MyWidget style={styles.welcome
// JS端的方法名={this.某方法.bind(this)}> </MyWidget> </View> );}
@Nullable
@Override
public Map getExportedCustomDirectEventTypeConstants() {
Map<String, Map<String, String>> map = new HashMap<>();
//mapBuilder.put("Android裡面的方法名", MapBuilder.of("registrationName", "JS端的方法名"));
map.put("onMapInitialed", MapBuilder.of("registrationName", "onMapInitialed"));
map.put("onRegionChange", MapBuilder.of("registrationName", "onRegionChange"));
map.put("onRegionChangeComplete", MapBuilder.of("registrationName", "onRegionChangeComplete"));
map.put("onDrivingRoutePlanComplete", MapBuilder.of("registrationName", "onDrivingRoutePlanComplete"));
map.put("onDrivingRoutePlanFailed", MapBuilder.of("registrationName", "onDrivingRoutePlanFailed"));
map.put("onRegionChangeCompleteWithReGeoResult", MapBuilder.of("registrationName", "onRegionChangeCompleteWithReGeoResult"));
map.put("onRegionChangeCompleteWithReGeoResultFailed", MapBuilder.of("registrationName", "onRegionChangeCompleteWithReGeoResultFailed"));
map.put("onFailToLocateUser", MapBuilder.of("registrationName", "onFailToLocateUser"));
return map;
}
/**
*
* @param id viewId
* @param eventName Android原生事件名
* @param event 傳回的參數
*/
public static void sendEvent(int id, String eventName, @Nullable WritableMap event) {
reactContext.getJSModule(RCTEventEmitter.class)
.receiveEvent(id, eventName, event);
}
}
AMapModule
代碼注解
- 幫助viewManager暴露一下方法給外部js使用
/**
* 跳轉到指定的位置
*/
@ReactMethod
@SuppressWarnings("unused")
public void changeCamera(int tag, ReadableMap readableMap) {
mapView = ((MyAMapView) reactContext.getCurrentActivity().findViewById(tag));
LatLng latLng = new LatLng(readableMap.getDouble(longitude), readableMap.getDouble(latitude));
mapView.changeCamera(
CameraUpdateFactory.newCameraPosition(new CameraPosition(latLng
, , , )));
MarkerUtil.addMarkersToMap(mapView.getAmap(), latLng, "title", "");
}
-
tag為js傳過來的id
findNodeHandle(this) 傳遞View Id給RN module
mapView = ((MyAMapView) reactContext.getCurrentActivity().findViewById(tag));
代碼
package com.aiyunbao;
import android.app.Activity;
import android.content.Intent;
import com.aiyunbao.Geocoder.GeocoderBiz;
import com.aiyunbao.aMap.MyAMapView;
import com.aiyunbao.activty.DirveNaviActivity;
import com.aiyunbao.location.LocationBiz;
import com.aiyunbao.marker.MarkerUtil;
import com.aiyunbao.poi.PoiSearchBiz;
import com.amap.api.maps.CameraUpdateFactory;
import com.amap.api.maps.model.CameraPosition;
import com.amap.api.maps.model.LatLng;
import com.amap.api.services.core.LatLonPoint;
import com.amap.api.services.poisearch.PoiSearch;
import com.facebook.react.bridge.Callback;
import com.facebook.react.bridge.JSApplicationIllegalArgumentException;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.ReadableMap;
/**
* Created by aiyun-pc1 on 2017/5/9.
*
*/
public class AMapModule extends ReactContextBaseJavaModule {
private ReactApplicationContext reactContext;
private MyAMapView mapView;
private final String longitude = "lng";
private final String latitude = "lat";
//poi搜尋
private PoiSearch.Query query;
private PoiSearch poiSearch;
private PoiSearchBiz poiSearchBiz;
//地理編碼
private GeocoderBiz geocoderBiz;
public AMapModule(ReactApplicationContext reactContext) {
super(reactContext);
this.reactContext = reactContext;
}
@Override
public String getName() {
return "AMap";
}
private void setMyAMapView(int tag) {
if (mapView == null) {
mapView = ((MyAMapView) reactContext.getCurrentActivity().findViewById(tag));
}
}
private void setGeocoderBiz() {
if (geocoderBiz == null) {
geocoderBiz = new GeocoderBiz(reactContext);
}
}
/**
* 跳轉到指定的位置
*/
@ReactMethod
@SuppressWarnings("unused")
public void changeCamera(int tag, ReadableMap readableMap) {
mapView = ((MyAMapView) reactContext.getCurrentActivity().findViewById(tag));
LatLng latLng = new LatLng(readableMap.getDouble(longitude), readableMap.getDouble(latitude));
mapView.changeCamera(
CameraUpdateFactory.newCameraPosition(new CameraPosition(latLng
, , , )));
MarkerUtil.addMarkersToMap(mapView.getAmap(), latLng, "title", "");
}
/**
* 在地圖上添加marker
*/
@ReactMethod
@SuppressWarnings("unused")
public void addMarkersToMap(int tag, ReadableMap readableMap) {
setMyAMapView(tag);
LatLng latLng = new LatLng(readableMap.getDouble(longitude), readableMap.getDouble(latitude));
MarkerUtil.addMarkersToMap(mapView.getAmap(), latLng);
}
/**
* 在地圖上添加marker,并繪制地圖上的資訊視窗
*/
@ReactMethod
@SuppressWarnings("unused")
public void addMarkersWithInfoToMap(int tag, ReadableMap readableMap, String title, String detail) {
setMyAMapView(tag);
LatLng latLng = new LatLng(readableMap.getDouble(longitude), readableMap.getDouble(latitude));
MarkerUtil.addMarkersToMap(mapView.getAmap(), latLng, title, detail);
}
/**
* 清空地圖上所有已經标注的marker
*/
@ReactMethod
@SuppressWarnings("unused")
public void clearAllMarker(int tag) {
setMyAMapView(tag);
MarkerUtil.clearMarker(mapView.getAmap());
}
/**
* 開始進行poi搜尋
*
*/
@ReactMethod
@SuppressWarnings("unused")
public void getPOISearchResult(ReadableMap params, Callback result, Callback error) {
/**
* {
// keywords: "武侯祠",
// city: "成都",
// offset: 10,
// },
*/
String keywords = params.getString("keywords");
String city = params.getString("city");
double latitude = ;
double longitude = ;
int radius = ;
int pageSize = params.getInt("offset");
LatLonPoint latLonPoint = new LatLonPoint(latitude, longitude);
if (poiSearchBiz == null)
poiSearchBiz = new PoiSearchBiz(reactContext, mapView);
poiSearchBiz.doSearchQuery(keywords, city, pageSize, radius, latLonPoint, result, error);
}
/**
* 開始進行poi搜尋
*
*/
@ReactMethod
@SuppressWarnings("unused")
public void getPOIAroundSearchResult(ReadableMap params, Callback result, Callback error) {
/**
* keywords: "天府廣場",
// city: "成都",
// latitude: 30.648623,
// longitude: 104.040568,
// radius: 3000
*/
String keywords = params.getString("keywords");
String city = params.getString("city");
double latitude = params.getDouble("latitude");
double longitude = params.getDouble("longitude");
int radius = params.getInt("radius");
int pageSize = ;
LatLonPoint latLonPoint = new LatLonPoint(latitude, longitude);
if (poiSearchBiz == null)
poiSearchBiz = new PoiSearchBiz(reactContext, mapView);
poiSearchBiz.doSearchQuery(keywords, city, pageSize, radius, latLonPoint, result, error);
}
/**
* 跳轉到指定的poi結果頁中
*/
@ReactMethod
@SuppressWarnings("unused")
public void selectPoiPage(int page, Callback callback) {
if (poiSearchBiz != null) {
poiSearchBiz.selectPoiPage(page, callback);
} else {
callback.invoke("請先使用poi查詢再跳轉指定的結果頁");
}
}
/**
* poi搜尋自動提示
*
* @param newText
* @param city 傳入null或者“”代表在全國進行檢索,否則按照傳入的city進行檢索
* @param tipCallback
*/
@ReactMethod
@SuppressWarnings("unused")
public void poiInputTip(int tag, String newText, String city, Callback tipCallback) {
setMyAMapView(tag);
poiSearchBiz = new PoiSearchBiz(reactContext, mapView);
poiSearchBiz.poiInputTip(newText, city, tipCallback);
}
// @ReactMethod
// @SuppressWarnings("unused")
// public void searchRouteResult(int tag) {
// setMyAMapView(tag);
// DriveRouteBiz driveRouteBiz = new DriveRouteBiz(reactContext, mapView);
// driveRouteBiz.searchRouteResult(ROUTE_TYPE_DRIVE, RouteSearch.DrivingDefault);
// }
@ReactMethod
@SuppressWarnings("unused")
public void driveNavi(int tag) {
try {
Activity currentActivity = getCurrentActivity();
if (null != currentActivity) {
Intent intent = new Intent(currentActivity, DirveNaviActivity.class);
intent.putExtra("data", "data");
currentActivity.startActivity(intent);
}
} catch (Exception e) {
throw new JSApplicationIllegalArgumentException(
"Could not open the activity : " + e.getMessage());
}
}
@ReactMethod
@SuppressWarnings("unused")
public void startLocationOneTime(Boolean isOnceLocation, Callback callback, Callback error) {
LocationBiz locationBiz = new LocationBiz(reactContext);
locationBiz.startLocation(isOnceLocation, callback, error);
}
@ReactMethod
@SuppressWarnings("unused")
public void getGeoCoding(String name, Callback callback) {
setGeocoderBiz();
geocoderBiz.getGeoCoding(name, callback);
}
@ReactMethod
@SuppressWarnings("unused")
public void getReGeoCoding(double lat, double lng, Callback callback) {
setGeocoderBiz();
geocoderBiz.getReGeoCoding(lat, lng, callback);
}
@ReactMethod
public void startLocationOneTime() {
}
}
AMapPackage
package com.aiyunbao;
import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.JavaScriptModule;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.uimanager.ViewManager;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
/**
* Created by aiyun-pc1 on 2017/5/8.
*/
public class AMapPackage implements ReactPackage {
@Override
public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
return Arrays.<NativeModule>asList(
new AMapModule(reactContext)
);
}
@Override
public List<Class<? extends JavaScriptModule>> createJSModules() {
return Collections.emptyList();
}
@Override
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
return Arrays.<ViewManager>asList(
new AMapViewManager(reactContext),
new ANaviMapViewManager(reactContext)
);
}
}
MainApplication
package com.aiyunbao;
import android.app.Application;
import com.facebook.react.ReactApplication;
import com.facebook.react.ReactNativeHost;
import com.facebook.react.ReactPackage;
import com.facebook.react.shell.MainReactPackage;
import com.facebook.soloader.SoLoader;
import java.util.Arrays;
import java.util.List;
public class MainApplication extends Application implements ReactApplication {
private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
@Override
public boolean getUseDeveloperSupport() {
return BuildConfig.DEBUG;
}
@Override
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
new MainReactPackage(),
new AMapPackage()
);
}
};
@Override
public ReactNativeHost getReactNativeHost() {
return mReactNativeHost;
}
@Override
public void onCreate() {
super.onCreate();
SoLoader.init(this, /* native exopackage */ false);
}
}
js代碼
/**
* Created by aiyun-pc1 on 2017/5/8.
*/
import React, {Component, PropTypes} from 'react';
import {
NativeAppEventEmitter,
NativeModules,
Platform,
StyleSheet,
requireNativeComponent,
View,
findNodeHandle,
} from 'react-native';
const MapManager = NativeModules.AMapModuleAndroid;
const MapView = requireNativeComponent('RCTAMapView', AMapViewTest);
export default class AMapViewTest extends Component {
static propTypes = {
...View.propTypes, // 包含預設的View的屬性
LatLng: PropTypes.object,
PAGESIZE: PropTypes.number,
RADIUS: PropTypes.number,
QUERYTYPE: PropTypes.string,
UISETTING: PropTypes.object,
onPoiSearch: PropTypes.func.isRequired,
onMapViewCenterChangeFinish: PropTypes.func,
onMapInitialed: PropTypes.func
};
static defaultProps = {};
_onMapInitialed = (event) => {
if (!this.props.onMapInitialed) {
return;
}
this.props.onMapInitialed(event.nativeEvent);
};
render() {
return (
<MapView
{...this.props}
onMapInitialed={this._onMapInitialed}
/>
);
}
// findNodeHandle(this) 傳遞View Id給RN module
// getCenterLocation() {
// MapManager.getCenterLocation(findNodeHandle(this))
// }
/**
* 39.90403, 116.407525 // 北京市經緯度
39.983456, 116.3154950// 北京市中關村經緯度
31.238068, 121.501654 // 上海市經緯度
39.989614, 116.481763 // 方恒國際中心經緯度
30.679879, 104.064855 // 成都市經緯度
34.341568, 108.940174 // 西安市經緯度
34.7466, 113.625367 // 鄭州市經緯度
* @constructor
*/
testMapMethod() {
let latlng = {
'lng': 34.7466,
'lat': 113.625367
};
let latlng1 = {
'lng': 34.341568,
'lat': 108.940174
};
let latlng2 = {
'lng': 30.679879,
'lat': 104.064855
};
let latlng3 = {
'lng': 39.989614,
'lat': 116.481763
};
// MapManager.test(findNodeHandle(this));
// MapManager.changeCamera(findNodeHandle(this), latlng);
// MapManager.addMarkersWithInfoToMap(findNodeHandle(this), latlng, '鄭州市經緯度', '鄭州市經緯度');
// MapManager.addMarkersWithInfoToMap(findNodeHandle(this), latlng1, '西安市經緯度', '西安市經緯度');
// MapManager.addMarkersWithInfoToMap(findNodeHandle(this), latlng2, '成都市經緯度', '成都市經緯度');
// MapManager.addMarkersToMap(findNodeHandle(this), latlng3);
MapManager.driveNavi(findNodeHandle(this));
}
/**
* 開始進行poi搜尋
* @param keyWord
* @param area 地區可以傳空字元,空字元代表全國
* @param pageSize
*/
searchPoi(keyWord, area, pageSize) {
MapManager.searchPoi(findNodeHandle(this), keyWord, area, pageSize);
}
/**
* 跳轉到指定的poi結果頁中
* @param page
* @param callback
*/
selectPoiPage(page, callback) {
MapManager.selectPoiPage(page, callback);
}
/**
* poi搜尋自動提示
* @param newText
* @param city 傳入null或者“”代表在全國進行檢索,否則按照傳入的city進行檢索
* @param callback
*/
poiInputTip(newText, city, callback) {
MapManager.poiInputTip(findNodeHandle(this), newText, city, callback);
}
searchRouteResult() {
MapManager.searchRouteResult(findNodeHandle(this));
}
startSmoothMove() {
MapManager.startSmoothMove(findNodeHandle(this));
}
}

- 以上代碼并不是最終修訂版,還有一些原生的高德地圖類沒上傳 如果需要幫助可以在文章中回複我
參考了以下大神的部落格
1. http://blog.csdn.net/qq_20738965/article/details/53363142