React-Native 集成AMap实例
来源:互联网 发布:兰州知豆电动车租赁点 编辑:程序博客网 时间:2024/06/06 09:25
前言
地图、定位对于移动开发来说不可或缺,下面尝试封装高德地图作为 React-Native组件。我只写了android部分,ios如有需求请移驾我公司大神发布的组件https://github.com/react-native-component/react-native-smart-amap
账号与Key的申请
注册成为高德开发者需要分三步:
第一步,注册高德开发者;第二步,去控制台创建应用;第三步,获取Key。
具体步骤:
1、注册高德开发者
2、创建应用
3、获取API key
申请地址:http://lbs.amap.com/
配置AndroidManifest.xml
//地图包、搜索包需要的基础权限<!--允许程序打开网络套接字--><uses-permission android:name="android.permission.INTERNET" /> <!--允许程序设置内置sd卡的写权限--><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <!--允许程序获取网络状态--><uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /><!--允许程序访问WiFi网络信息--><uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /><!--允许程序读写手机状态和身份--><uses-permission android:name="android.permission.READ_PHONE_STATE" /> <!--允许程序访问CellID或WiFi热点来获取粗略的位置--><uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
设置高德Key
gradle文件中添加
defaultConfig { minSdkVersion 19 targetSdkVersion 24 versionCode 1 versionName "1.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" manifestPlaceholders = [ AMAP_KEY:"你的 Appkey" ] }
在application标签中加入:
<meta-data android:name="com.amap.api.v2.apikey" android:value="${AMAP_KEY}"/>
Android部分
使用AS创建Library项目,右键点击项目并选择Open Module Settings,选中Dependencies,点击下面等➕号选择Library dependency,搜索AMap添加导入就可以使用sdk了。
dependencies {... compile 'com.amap.api:map2d:2.9.1' compile 'com.amap.api:location:3.1.0' compile 'com.amap.api:search:3.5.0'}
原生UI
AMap动画比较卡,期间还造成定位不准确,建议不使用动画,定位后加图标,Poi搜索都在回调事件中处理,以下是RCTAMapView代码,定位功能,poi搜索功能,看个人需求也可以封装到原生模块中
public class RCTAMapView extends FrameLayout implements LocationSource, AMapLocationListener, PoiSearch.OnPoiSearchListener, AMap.OnCameraChangeListener { ... //定义一堆成员变量 .../** * 初始化View * @param context */ public RCTAMapView(ThemedReactContext context) { super(context); this.CONTEXT = context; CenterView = new ImageView(context);//空间中间显示到图标 Resources resources =context.getCurrentActivity().getResources(); DisplayMetrics dm = resources.getDisplayMetrics(); this.density = dm.density;// SCROLL_BY_PX=(int)(SCROLL_BY_PX*density+0.5); PARAM = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT); } /** * 初始化控件,定位位置 */ private void init() { mSensorHelper = new SensorEventHelper(CONTEXT); if (mSensorHelper != null) { mSensorHelper.registerSensorListener(); } MAPVIEW = new MapView(CONTEXT); MAPVIEW.setLayoutParams(PARAM); this.addView(MAPVIEW); MAPVIEW.onCreate(CONTEXT.getCurrentActivity().getIntent().getExtras()); CenterView.setLayoutParams(new ViewGroup.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.WRAP_CONTENT));// CenterView.setImageResource(R.drawable.poi_marker); CenterView.setImageResource(getSplashId(CENTERMARKER)); this.addView(CenterView, 1); setUpMap(); poiSearch = new PoiSearch(CONTEXT, query); } /** * 设置一些amap的属性 */ private void setUpMap() { AMAP = MAPVIEW.getMap(); AMAP.setMapType(AMap.MAP_TYPE_NORMAL);// 矢量地图模式 mUiSettings = AMAP.getUiSettings();//实例化UiSettings类 mUiSettings.setZoomControlsEnabled(ZOOMCONTROLS);//显示缩放按钮 mUiSettings.setZoomPosition(ZOOM_POSITION_RIGHT_CENTER);//缩放按钮 右边界中部:ZOOM_POSITION_RIGHT_CENTER 右下:ZOOM_POSITION_RIGHT_BUTTOM。 mUiSettings.setLogoPosition(LOGO_POSITION_BOTTOM_RIGHT);//Logo的位置 左下:LOGO_POSITION_BOTTOM_LEFT 底部居中:LOGO_POSITION_BOTTOM_CENTER 右下:LOGO_POSITION_BOTTOM_RIGHT mUiSettings.setCompassEnabled(COMPASSENABLE);//指南针 mUiSettings.setZoomGesturesEnabled(ZOOMGESTURES);//手势缩放 mUiSettings.setScaleControlsEnabled(SCALECONTROLS);//比例尺 changeCamera( CameraUpdateFactory.newCameraPosition(new CameraPosition( latLng, ZOOMLEVEL, 30, 0)));//创建view时候传入之前定位到当前坐标位置把地图中心移动过去 mFirstFix = true; addLocationMarker(latLng, RADIUS, mLocMarker); AMAP.setLocationSource(this);// 设置定位监听 AMAP.setOnCameraChangeListener(this);// 对amap添加移动地图事件监听器 mUiSettings.setMyLocationButtonEnabled(false);// 设置默认定位按钮是否显示 AMAP.setMyLocationEnabled(true);// 设置为true表示显示定位层并可触发定位,false表示隐藏定位层并不可触发定位,默认是false } /** * Activity onResume后调用view的onAttachedToWindow */ @Override protected void onAttachedToWindow() { init(); super.onAttachedToWindow(); } /** * 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(); } }
重写onLayout处理中心点图标位置
@Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) {/** * 处理中心点控件位置 */ HEIGHT = getHeight();//在这里才可以拿到控件到高低 WIDTH = getWidth(); FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) CenterView.getLayoutParams(); viewWidth = CenterView.getMeasuredWidth(); viewHeight = CenterView.getMeasuredHeight(); params.setMargins(WIDTH / 2 - viewWidth / 2, HEIGHT / 2 - viewHeight, 0, 0); CenterView.setLayoutParams(params);// CenterView.invalidate(); super.onLayout(changed, left, top, right, bottom); }
发起定位,发起poi搜索以及回调方法:
/** * 定位到设备定位位置 */ public void startLocation() { startTime = System.currentTimeMillis(); Log.i("Test", "startTime:" + startTime); if (mlocationClient == null) { Log.i("Test", "mlocationClient = null"); mlocationClient = new AMapLocationClient(CONTEXT); mLocationOption = new AMapLocationClientOption(); //设置定位监听 mlocationClient.setLocationListener(this); //设置为高精度定位模式 mLocationOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy); mLocationOption.setOnceLocation(ONCELOCATION);// mLocationOption.setOnceLocationLatest(true); mLocationOption.setLocationCacheEnable(true);//定位缓存策略// mLocationOption.setInterval(10);// mLocationOption.setInterval(3*60*1000); //设置定位参数 mlocationClient.setLocationOption(mLocationOption); // 此方法为每隔固定时间会发起一次定位请求,为了减少电量消耗或网络流量消耗, // 注意设置合适的定位时间的间隔(最小间隔支持为2000ms),并且在合适时间调用stopLocation()方法来取消定位请求 // 在定位结束后,在合适的生命周期调用onDestroy()方法 // 在单次定位情况下,定位无论成功与否,都无需调用stopLocation()方法移除请求,定位sdk内部会移除 } mlocationClient.startLocation(); } public void poiSearch(String keyWord, String cityCode, int currentPage) { query = new PoiSearch.Query(keyWord, QUERYTYPE, cityCode);//keyWord表示搜索字符串,//第二个参数表示POI搜索类型,二者选填其一,//POI搜索类型共分为以下20种:汽车服务|汽车销售|//汽车维修|摩托车服务|餐饮服务|购物服务|生活服务|体育休闲服务|医疗保健服务|//住宿服务|风景名胜|商务住宅|政府机构及社会团体|科教文化服务|交通设施服务|//金融保险服务|公司企业|道路附属设施|地名地址信息|公共设施//cityCode表示POI搜索区域,可以是城市编码也可以是城市名称,也可以传空字符串,空字符串代表全国在全国范围内进行搜索 query.setPageSize(PAGESIZE);// 设置每页最多返回多少条poiitem query.setPageNum(currentPage);//设置查询页码 poiSearch.setQuery(query); poiSearch.setOnPoiSearchListener(this); poiSearch.searchPOIAsyn(); } public void poiSearchRound(LatLonPoint latlng, String cityCode, int currentPage) { if (cityCode == null || "".equals( cityCode)) { cityCode = DEFAULTCITY; } query = new PoiSearch.Query("", QUERYTYPE, cityCode); query.setPageSize(PAGESIZE);// 设置每页最多返回多少条poiitem query.setPageNum(currentPage);//设置查询页码 poiSearch.setQuery(query); poiSearch.setOnPoiSearchListener(this); poiSearch.setBound(new PoiSearch.SearchBound(latlng, 1000));//设置周边搜索的中心点以及半径 poiSearch.searchPOIAsyn(); } private void addCircle(LatLng latlng, float RADIUS) { CircleOptions options = new CircleOptions(); options.strokeWidth(1f); options.fillColor(FILL_COLOR); options.strokeColor(STROKE_COLOR); options.center(latlng); options.radius(RADIUS); mCircle = AMAP.addCircle(options);/* ObjectAnimator radiusAnim = ObjectAnimator.ofFloat(mCircle, "radius", radius,0.0f,radius); radiusAnim.setDuration(1000); radiusAnim.setRepeatCount(ValueAnimator.INFINITE);//无限循环// translationYAnim.setRepeatMode(ValueAnimator.INFINITE); radiusAnim.start();*/ } private void addMarker(LatLng latlng) { if (mLocMarker != null) { return; }// Bitmap bMap = BitmapFactory.decodeResource(this.getResources(),// R.drawable.navi_map_gps_locked); Bitmap bMap = BitmapFactory.decodeResource(this.getResources(), getSplashId(LOCATIONMARKER)); BitmapDescriptor des = BitmapDescriptorFactory.fromBitmap(bMap);// BitmapDescriptor des = BitmapDescriptorFactory.fromResource(R.drawable.navi_map_gps_locked); MarkerOptions options = new MarkerOptions(); options.icon(des); options.anchor(0.5f, 0.5f); options.position(latlng); // 将Marker设置为贴地显示,可以双指下拉看效果 mLocMarker = AMAP.addMarker(options); } @Override public void activate(OnLocationChangedListener listener) { mListener = listener;// startLocation(); } @Override public void deactivate() { mListener = null; if (mlocationClient != null) { mlocationClient.stopLocation(); mlocationClient.onDestroy(); } mlocationClient = null; } /** * poi搜索回调 * @param result * @param rCode */ @Override public void onPoiSearched(PoiResult result, int rCode) { List<PoiItem> poiItems = new ArrayList<>(); if (rCode == 1000) { if (result != null && result.getQuery() != null) {// 搜索poi的结果 if (result.getQuery().equals(query)) {// 是否是同一条 poiResult = result; // 取得搜索到的poiitems有多少页 poiItems = poiResult.getPois();// 取得第一页的poiitem数据,页数从数字0开始 /* List<SuggestionCity> suggestionCities = poiResult .getSearchSuggestionCitys();// 当搜索不到poiitem数据时,会返回含有搜索关键字的城市信息*/ /* if (poiItems != null && poiItems.size() > 0) { for (PoiItem poi : poiItems) { //event发送 Log.i("Test", "PoiItem:" + poi.getCityName() + "," + poi.getAdName() + "," + poi.getTitle() + "," + poi.getSnippet() + "," + poi.getLatLonPoint().getLongitude()); } }*/ } } }// onEvChangeListener.getPoiItem(poiItems); sendPoi2RN(poiItems); } /** * 获得对应module 发送数据到RN * * @param poiItems */ private void sendPoi2RN(List<PoiItem> poiItems) { WritableMap event = Arguments.createMap(); WritableArray array = Arguments.createArray(); for (PoiItem poi : poiItems) { WritableMap data = Arguments.createMap(); data.putString("uid", poi.getPoiId()); data.putString("name", poi.getTitle()); data.putString("type", poi.getTypeDes()); data.putDouble("Longitude", poi.getLatLonPoint().getLongitude()); data.putDouble("Latitude", poi.getLatLonPoint().getLatitude()); data.putString("address", poi.getSnippet()); data.putString("tel", poi.getTel()); data.putInt("distance", poi.getDistance()); array.pushMap(data); } event.putArray("searchResultList", array); CONTEXT.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class) .emit("PoiEvent", event); } @Override public void onPoiItemSearched(PoiItem poiItem, int i) { }/** * 定位回调 * @param amapLocation */ @Override public void onLocationChanged(AMapLocation amapLocation) { if (!ISFIRSTMOVE) { ISFIRSTMOVE = true; } if (mListener != null && amapLocation != null) { if (amapLocation != null && amapLocation.getErrorCode() == 0) { location = new LatLng(amapLocation.getLatitude(), amapLocation.getLongitude());// Log.i("TEST", "getLatitude:"+amapLocation.getLatitude()+"getLongitude:"+amapLocation.getLongitude()); DEFAULTCITY = amapLocation.getCity(); if (!mFirstFix) { mFirstFix = true; addLocationMarker(location, RADIUS, mLocMarker);// 首次定位到点location// AMAP.moveCamera(CameraUpdateFactory.newLatLngZoom(location, ZOOMLEVEL)); } else { mCircle.setCenter(location); mCircle.setRadius(RADIUS); mLocMarker.setPosition(location); } //移动镜头定位到点location /*AMAP.moveCamera(CameraUpdateFactory.newLatLngZoom(location, ZOOMLEVEL));*/ changeCamera( CameraUpdateFactory.newCameraPosition(new CameraPosition( location, ZOOMLEVEL, 30, 0))); /* animateCamera(CameraUpdateFactory.newCameraPosition(new CameraPosition( location, ZOOMLEVEL, 30, 0)),null);*/ changeCamera(CameraUpdateFactory.scrollBy(0, -SCROLL_BY_PX)); } else { String errText = "定位失败," + amapLocation.getErrorCode() + ": " + amapLocation.getErrorInfo(); Log.i("TEST", errText); } } }
RCTAMapManager代码如下:
public class RCTAMapManager extends ViewGroupManager<RCTAMapView> { public static final LatLng SHANGHAI = new LatLng(31.238068, 121.501654);// 上海市经纬度 @Override public String getName() { return "RCTAMapView"; } @Override protected RCTAMapView createViewInstance(ThemedReactContext reactContext) {// SDKInitializer.initialize(reactContext.getApplicationContext()); RCTAMapView map=new RCTAMapView(reactContext);// map.startLocation(); return map; } @ReactProp(name = "LatLng") public void setLatLng(RCTAMapView view,ReadableMap Map) { if (Map == null) { view.setLatLng(SHANGHAI); return; } view.setLatLng(new LatLng(Map.getDouble("latitude"),Map.getDouble("longitude"))); } /** * 查询poi每页显示多少行 * @param view * @param pagesize */ @ReactProp(name = "PAGESIZE",defaultInt = 10) public void setPAGESIZE(RCTAMapView view,int pagesize) { view.setPAGESIZE(pagesize); } /** * 定位光圈半径 * @param view * @param RADIUS */ @ReactProp(name = "RADIUS",defaultInt = 10) public void setRADIUS(RCTAMapView view,int RADIUS) { view.setRADIUS(RADIUS); } /** * 定位光圈半径 * @param view * @param ZOOMLEVEL */ @ReactProp(name = "ZOOMLEVEL",defaultInt = 18) public void setZOOMLEVEL(RCTAMapView view,int ZOOMLEVEL) { view.setZOOMLEVEL(ZOOMLEVEL); } /** * poi查询类型 * //POI搜索类型共分为以下20种:汽车服务|汽车销售| //汽车维修|摩托车服务|餐饮服务|购物服务|生活服务|体育休闲服务|医疗保健服务| //住宿服务|风景名胜|商务住宅|政府机构及社会团体|科教文化服务|交通设施服务| //金融保险服务|公司企业|道路附属设施|地名地址信息|公共设施 * @param view * @param QUERYTYPE */ @ReactProp(name = "QUERYTYPE") public void setQUERYTYPE(RCTAMapView view,String QUERYTYPE) { if(QUERYTYPE!=null) { view.setQUERYTYPE(QUERYTYPE); } } /** * uisetting 初始化地图参数 * ZOOMCONTROLS 显示缩放按钮 ZOOMGESTURES 手势缩放 SCALECONTROLS 显示比例尺 COMPASSENABLE 显示指南针 ONCELOCATION 是否一次定位 LOCATIONMARKER 定位图片资源名称 CENTERMARKER 中心点图片资源名称 * @param view * @param Map */ @ReactProp(name = "UISETTING") public void setUISETTING(RCTAMapView view,ReadableMap Map) { if(Map!=null) { if( Map.hasKey("ZOOMCONTROLS")) view.setZOOMCONTROLS(Map.getBoolean("ZOOMCONTROLS")); if( Map.hasKey("ZOOMGESTURES")) view.setZOOMGESTURES(Map.getBoolean("ZOOMGESTURES")); if( Map.hasKey("SCALECONTROLS")) view.setSCALECONTROLS(Map.getBoolean("SCALECONTROLS")); if( Map.hasKey("COMPASSENABLE")) view.setCOMPASSENABLE(Map.getBoolean("COMPASSENABLE")); if( Map.hasKey("ONCELOCATION")) view.setCOMPASSENABLE(Map.getBoolean("ONCELOCATION")); if( Map.hasKey("CENTERMARKER")) view.setCENTERMARKER(Map.getString("CENTERMARKER")); if( Map.hasKey("LOCATIONMARKER")) view.setLOCATIONMARKER(Map.getString("LOCATIONMARKER")); } } @Override protected void addEventEmitters( final ThemedReactContext reactContext, final RCTAMapView view) { view.setOnEvChangeListener( new RCTAMapView.OnEvChangeListener() { @Override public void getPoiItem(List<PoiItem> poiItem) { reactContext.getNativeModule(UIManagerModule.class).getEventDispatcher() .dispatchEvent(new PoiEvent(view.getId(),poiItem)); } }); } @Override public Map<String, Object> getExportedCustomDirectEventTypeConstants() { return MapBuilder.<String, Object>builder() .put("PoiItemEvent", MapBuilder.of("registrationName", "onPoiSearch"))//registrationName 后的名字,RN中方法也要是这个名字否则不执行 .put("onViewCenterChangeFinish", MapBuilder.of("registrationName", "onMapViewCenterChangeFinish"))//registrationName 后的名字,RN中方法也要是这个名字否则不执行 .build(); }}
原生模块
RCTLBSModule代码如下:
public class RCTLBSModule extends ReactContextBaseJavaModule { ReactApplicationContext mContext; private AMapLocationClient locationClient = null; private AMapLocationClientOption locationOption = new AMapLocationClientOption();boolean ADDRESSCHECK,GPSCHECK,CACHECHECK,LATESTCHECK,SENSORCHECK; long STRINTERVAL=2000; long TIMEOUT =30000; public RCTLBSModule(ReactApplicationContext reactContext) { super(reactContext); mContext = reactContext; LATESTCHECK=true; } @Override public String getName() { return "LBSModule"; } /** * 开启定位服务 */ @ReactMethod public void startLocationService() { /** * 创建定位请求 */ mContext.getCurrentActivity().runOnUiThread(new Runnable() { public void run() {// if(mLocationClient==null) {// initLocation();// }// mLocationClient.start(); if (locationClient == null) { initLocation(); } startLocation(); } }); } /* @ReactMethod public void getCenterLocation(final int tag){ mContext.getCurrentActivity().runOnUiThread(new Runnable() { public void run() { final RCTAMapView Map = ((RCTAMapView) mContext.getCurrentActivity().findViewById(tag)); Map.getCenterLocation(); } }); }*/ @ReactMethod public void setCenterLocation(final int tag,final double latitude,final double longitude){ mContext.getCurrentActivity().runOnUiThread(new Runnable() { public void run() { final RCTAMapView Map = ((RCTAMapView) mContext.getCurrentActivity().findViewById(tag)); Map.setCenterLocation(latitude,longitude); } }); } @ReactMethod public void startLocation(int tag){ final RCTAMapView Map = ((RCTAMapView) mContext.getCurrentActivity().findViewById(tag)); Map.startLocation(); } @ReactMethod public void poiSearch(int tag,String keyWord,String cityCode,int currentPage){ final RCTAMapView Map = ((RCTAMapView) mContext.getCurrentActivity().findViewById(tag)); Map.poiSearch(keyWord,cityCode,currentPage); } @ReactMethod public void poiSearchRound(int tag,final double latitude,final double longitude,String cityCode,int currentPage){ final RCTAMapView Map = ((RCTAMapView) mContext.getCurrentActivity().findViewById(tag)); Map.poiSearchRound(new LatLonPoint(latitude,longitude),cityCode,currentPage); } /** * 初始化定位 * * @author hongming.wang * @since 2.8.0 */ private void initLocation() { //初始化client locationClient = new AMapLocationClient(mContext.getApplicationContext()); //设置定位参数 locationClient.setLocationOption(getDefaultOption()); // 设置定位监听 locationClient.setLocationListener(locationListener); } /** * 默认的定位参数 * * @author hongming.wang * @since 2.8.0 */ private AMapLocationClientOption getDefaultOption() { AMapLocationClientOption mOption = new AMapLocationClientOption(); mOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);//可选,设置定位模式,可选的模式有高精度、仅设备、仅网络。默认为高精度模式 mOption.setGpsFirst(false);//可选,设置是否gps优先,只在高精度模式下有效。默认关闭 mOption.setHttpTimeOut(TIMEOUT);//可选,设置网络请求超时时间。默认为30秒。在仅设备模式下无效 mOption.setInterval(STRINTERVAL);//可选,设置定位间隔。默认为2秒 mOption.setNeedAddress(true);//可选,设置是否返回逆地理地址信息。默认是true mOption.setOnceLocation(false);//可选,设置是否单次定位。默认是false mOption.setOnceLocationLatest(true);//可选,设置是否等待wifi刷新,默认为false.如果设置为true,会自动变为单次定位,持续定位时不要使用 AMapLocationClientOption.setLocationProtocol(AMapLocationClientOption.AMapLocationProtocol.HTTP);//可选, 设置网络请求的协议。可选HTTP或者HTTPS。默认为HTTP mOption.setSensorEnable(false);//可选,设置是否使用传感器。默认是false return mOption; } /** * 定位监听 */ AMapLocationListener locationListener = new AMapLocationListener() { @Override public void onLocationChanged(AMapLocation loc) { if (null != loc) { //解析定位结果 String LocationData = Utils.getLocationStr(loc); WritableMap params = Arguments.createMap(); params.putString("AMapLocation", LocationData); sendEvent(mContext, "onAMAPLocationResult", params); } else { } } }; // 根据控件的选择,重新设置定位参数 private void resetOption() { // 设置是否需要显示地址信息 locationOption.setNeedAddress(ADDRESSCHECK); /** * 设置是否优先返回GPS定位结果,如果30秒内GPS没有返回定位结果则进行网络定位 * 注意:只有在高精度模式下的单次定位有效,其他方式无效 */ locationOption.setGpsFirst(GPSCHECK); // 设置是否开启缓存 locationOption.setLocationCacheEnable(CACHECHECK); //设置是否等待设备wifi刷新,如果设置为true,会自动变为单次定位,持续定位时不要使用 locationOption.setOnceLocationLatest(LATESTCHECK); //设置是否使用传感器 locationOption.setSensorEnable(SENSORCHECK); try { // 设置发送定位请求的时间间隔,最小值为1000,如果小于1000,按照1000算 locationOption.setInterval(STRINTERVAL); } catch (Throwable e) { e.printStackTrace(); } try { // 设置网络请求超时时间 locationOption.setHttpTimeOut(TIMEOUT); } catch (Throwable e) { e.printStackTrace(); } } /** * 开始定位 * * @author hongming.wang * @since 2.8.0 */ private void startLocation() { //根据控件的选择,重新设置定位参数 resetOption(); // 设置定位参数 locationClient.setLocationOption(locationOption); // 启动定位 locationClient.startLocation(); } /** * 停止定位 * * @author hongming.wang * @since 2.8.0 */ private void stopLocation() { // 停止定位 locationClient.stopLocation(); } /** * 销毁定位 * * @author hongming.wang * @since 2.8.0 */ @ReactMethod private void destroyLocation() { if (null != locationClient) { /** * 如果AMapLocationClient是在当前Activity实例化的, * 在Activity的onDestroy中一定要执行AMapLocationClient的onDestroy */ locationClient.onDestroy(); locationClient = null; locationOption = null; } } @ReactMethod public void stopLocationService() { stopLocation(); } private void sendEvent(ReactContext reactContext, String eventName, @Nullable WritableMap params) { reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class) .emit(eventName, params); }
JS部分
组件部分封装到这里就结束啦 amap.js如下
import React, { Component, PropTypes } from 'react';import { NativeAppEventEmitter, NativeModules, Platform, StyleSheet, requireNativeComponent, View, findNodeHandle,} from 'react-native';const MapManager = NativeModules.LBSModule;const MapView = requireNativeComponent('RCTAMapView', AMapView);export default class AMapView extends Component { static defaultProps = {} 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, } render() { return ( <MapView {...this.props} /> ); } //findNodeHandle(this) 传递View Id给RN module getCenterLocation() { MapManager.getCenterLocation(findNodeHandle(this)) } startLocation() { MapManager.startLocation(findNodeHandle(this)) } poisearch(keyWord, i,page) { MapManager.poiSearch(findNodeHandle(this), keyWord, i, page) } poiSearchRound(latitude,longitude, i,page) { MapManager.poiSearchRound(findNodeHandle(this), latitude,longitude ,i, page) }}
RN中使用amap
import React, { Component,} from 'react'import { View, Text, StyleSheet, Alert, ScrollView, ListView, TextInput, Image, ActivityIndicator, ProgressBarAndroid, ActivityIndicatorIOS, TouchableHighlight, Platform, DeviceEventEmitter,} from 'react-native'import AMapView from './aMap'import TimerEnhance from 'react-native-smart-timer-enhance'let componentData = {}let dataSource = new ListView.DataSource({ rowHasChanged: (r1, r2) => { return r1 !== r2 }, sectionHeaderHasChanged: (s1, s2) => { return s1 !== s2 },})let FirstEdit=0;//判断输入时间class MapView extends Component { constructor(props) { super(props); // 初始状态 this.state = { value: '', componentDataSource: dataSource.cloneWithRows(componentData), }; } componentDidMount() { DeviceEventEmitter.addListener('PoiEvent', this.handleAndroidMessage); } componentWillUnMount() { //移除监听返回键 DeviceEventEmitter.removeListener('PoiEvent'); //关闭定位 //NativeModules.LBSModule.destroyLocation() } handleAndroidMessage = (e)=> { let array=e.searchResultList; if(this.refs.TextInput.value!='') { this.setState({componentDataSource: this.state.componentDataSource.cloneWithRows(array)}); } }/*<Text onPress={this._getCenterLocation}style={{position: 'absolute', bottom: 0, right: 0, padding: 20, fontSize: 24,}}>中心</Text>*/ render() { return ( <View style={{flex:1,flexDirection:'column',justifyContent:'center'}}> <View style={{flex:1}}> <AMapView style={{flex:1}} LatLng={{latitude:31.239201,longitude:121.431598}} ref={ component => this._MapView = component } onPoiSearch={this._onPoiSearch} onMapViewCenterChangeFinish={this._onMapViewCenterChangeFinish} UISETTING={{CENTERMARKER:'poi_marker'}} /> <TouchableHighlight underlayColor={'#ccc'} style={{position: 'absolute', bottom: 10, left: 10, padding: 10, backgroundColor: '#fff',}} onPress={this._startLocation}> <Text style={{flex:1,fontSize: 20,}} >定位</Text> </TouchableHighlight> </View> <View style={{flex:1,flexDirection:'column',justifyContent:'center'}}> <TextInput ref="TextInput" style={[styles.input]} placeholder="请输入名称" maxLength={20} clearButtonMode="while-editing" value={this.state.value} onChangeText={this._changeText.bind(this)} underlineColorAndroid="transparent"//删除下划线 //onSubmitEditing={this._onSubmitEditing.bind(this)} /> <ListView dataSource={this.state.componentDataSource} enableEmptySections={true} renderRow={this._renderRow} style={{flex:1}}/> </View> </View> ) } _renderRow = (rowData) => { return ( <Text style={styles.item}>{rowData.name+','+rowData.address+','+rowData.distance }</Text> ) } _startLocation = (e)=> { this._MapView.startLocation() } _getCenterLocation = (e)=> { this._MapView.getCenterLocation() } /* _onSubmitEditing = ()=> { if (value === '') { this.setState({componentDataSource: this.state.componentDataSource.cloneWithRows(componentData)}); } else { this._MapView.poisearch(value, '上海') } }*/ _changeText = (e)=> { let timestamp = (new Date()).valueOf(); if (timestamp - FirstEdit > 1000) { FirstEdit = timestamp; if (e === '') { this.setState({componentDataSource: this.state.componentDataSource.cloneWithRows(componentData)}); } else { this._MapView.poisearch(e, '',0) } } if (e === '') { this.setState({componentDataSource: this.state.componentDataSource.cloneWithRows(componentData)}); } this.setState({value: e}); } _onPoiSearch=(e)=>{ let array=e.nativeEvent.searchResultList; if(this.refs.TextInput.value!='') { this.setState({componentDataSource: this.state.componentDataSource.cloneWithRows(array)}); } } _onMapViewCenterChangeFinish=(e)=>{ this._MapView.poiSearchRound(e.nativeEvent.latitude, e.nativeEvent.longitude,'',0) }}let styles = StyleSheet.create({ header: { height: 40, flexDirection: 'row', justifyContent: 'flex-start', backgroundColor: '#F0F0FF', alignItems: 'stretch', top: 20, }, flex: { flex: 1 }, item: { height: 30, //borderBottomWidth: StyleSheet.hairlineWidth, //borderBottomColor: '#ccc', overflow: 'hidden', justifyContent: 'center', alignItems: 'flex-start', }, search: { flex: 1, height: 30, backgroundColor: '#fff', alignItems: 'stretch', borderWidth: 1, borderColor: '#ccc', borderRadius: 4, flexDirection: 'row', }, input: { height: 40, borderWidth: 1, borderColor: '#ccc', borderRadius: 4, backgroundColor: '#ffff' }, result: { flex: 1, backgroundColor: '#fff', }, border: { borderWidth: 1, borderTopWidth: 0, borderColor: '#ccc', borderRadius: 4, }, height30: { height: 30, }, marginTop5: { marginTop: 5, }, search_view: { top: 5, right: 0, width: 300, marginRight: 5, justifyContent: 'flex-start', alignItems: 'stretch', position: 'absolute', flexDirection: 'column', },});export default TimerEnhance(MapView)
因为是模拟器演示,定位的时候没有触发,效果如下:
0 0
- React-Native 集成AMap实例
- Amap location for React Native 高德定位
- react-native 与高德地图(amap)原生互相调用
- React Native集成Redux
- React Native & Android集成
- react native android集成
- React Native 集成 Redux
- React Native 集成jpush-react-native
- React Native实例
- ios原生集成React Native
- React Native 集成到已有项目
- React Native 集成流水帐
- ios集成react-native步骤
- React-Native-iOS推送集成
- React Native安卓微信分享集成
- android stadio集成React-native
- react-native 集成极光推送
- react-native 集成支付宝
- 栈
- OpenGL--代码解读
- /etc目录介绍
- @RequestBody接收json字符串,自动将日期字符串转换为java.util.Date
- 独木舟问题
- React-Native 集成AMap实例
- Android学习11
- poj3468-线段树详解
- 作业:计数器仿真实验
- Ubuntu下切换JDK版本
- 算法学习和整理
- SVN使用教程
- Android学习12
- Form1