react native android 高德地图原生代码编写

编程知识 更新时间:2023-04-07 00:28:46

react native android 高德地图原生代码编写

  • react native android 高德地图原生代码编写
    • android代码
      • MyAmapView
        • 高德地图注意事项
        • 代码
      • AMapViewManager
        • 代码注解
        • viewManager如何被外部的js调用的
        • error
        • 代码
      • AMapModule
        • 代码注解
        • 代码
      • AMapPackage
      • MainApplication
    • js代码

android代码

MyAmapView

高德地图注意事项

  • key授权失败
    请注意包含高德key的meta-data标签是否被包含在application标签中
  • 高德地图无法显示
    1. 先查看一下rn中地图view是否占了位置没有显示,设置rn中的view的背景颜色可查看,rnview的大小设置没.如果占了位置,检查是否调用mapView.onCreate();
    2. 使用frameLayout请检查是否调用this.addView()
  • 以下就是部分代码

代码


因为公司原因,贴出部分代码,有需要的可以直接从里面拷贝一些代码来用

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(180, 3, 145, 255);
    private static final int FILL_COLOR = Color.argb(10, 0, 0, 180);
    /**
     * 传感器
     */
    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(1f);
        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(0.5f, 0.5f);
        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(2000);
        // 自定义定位蓝点图标
        myLocationStyle.myLocationIcon(BitmapDescriptorFactory.
                fromResource(R.drawable.gps_point));
        // 自定义精度范围的圆形边框颜色
        myLocationStyle.strokeColor(STROKE_COLOR);
        //自定义精度范围的圆形边框宽度
        myLocationStyle.strokeWidth(5);
        // 设置圆形的填充颜色
        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", "", 3000, 20, 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调用的

  1. viewManager通过Module来暴露方法
  2. 通过属性的更新来调用
/**
     * 设置线路规划参数
     */
    @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


  1. 属性不能更新
    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.reactmon.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
                        , 18, 30, 30)));
        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
                        , 18, 30, 30)));
        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 = 0;
        double longitude = 0;
        int radius = 0;
        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 = 20;
        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/qq_20738965/article/details/53363142

更多推荐

react native android 高德地图原生代码编写

本文发布于:2023-04-07 00:28:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/1bbecd391ca899ec148b58e84d3dcb42.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:代码   地图   react   native   android

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!

  • 51384文章数
  • 14阅读数
  • 0评论数