天天看点

Weex地图组件开发流程及使用(android)

一、组件开发前准备

   首先,新建高德地图开发者账号,获取地图的key。

   进入自己的高德开发账号,点击‘创建新应用’  

Weex地图组件开发流程及使用(android)

创建应用完成点击右上角的添加新key

Weex地图组件开发流程及使用(android)
Weex地图组件开发流程及使用(android)

发布版SHA1以及调试版SHA1获取:

1、打开android studio 找到Terminal并打开,或者在最下面找到Terminal 如下图:

Weex地图组件开发流程及使用(android)

2、 输入命令  C:    进入c盘;

3、接着 输入命令   cd Users\Administrator   其中Administrator是自己的用户名  Administrator文件下有个.adnroid文件, 输入命令   cd  .android,最后就找到了.android,如图:

Weex地图组件开发流程及使用(android)

4、输入命令  keytool -list -v -keystore debug.keystore  其中debug.keystore是studio默认的keystore,按回车,然后输入秘钥:android(系统默认)    回车(秘钥库口令是看不到的)如下图:

Weex地图组件开发流程及使用(android)

这样就成功获取到开发版的SHA1值了

二、获取发布版的SHA1:

获取发布版的SHA1,跟获取开发版的SHA1的1、2、3步骤一样,不一样的地方就是第4步稍微不同而已。

1、同上;

2、同上;

3、同上;

4、输入命令  keytool -list -v -keystore 文件目录\自己的签名文件 比如我的:keytool -list -v -keystore E:\签名文件\android.keystore ,接着按回车,然后输入秘钥:(我只知道我的,哈哈)    回车(秘钥库口令是看不到的)如下图:

Weex地图组件开发流程及使用(android)

这样就成功获取到发布版的SHA1值了

Weex地图组件开发流程及使用(android)

在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" />

添加高德地图的apiKey

Weex地图组件开发流程及使用(android)

在app的build.gradle中添加相关依赖:

Weex地图组件开发流程及使用(android)
Weex地图组件开发流程及使用(android)

二、组件开发

1、自定义MapView控件

  新建布局文件location_layout.xml。布局文件里主要放了一个mapView控件。

Weex地图组件开发流程及使用(android)

  新建WeexMapView继承LinearLayout类,开发一个自定义的组合组件。

Weex地图组件开发流程及使用(android)

public void setMapModel(int model){

    switch (model){

        case 1://连续定位、蓝点不会移动到地图中心点,定位点依照设备方向旋转,并且蓝点会跟随设备移动。

            myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE_NO_CENTER);

            break;

        case 2://连续定位、且将视角移动到地图中心点,定位蓝点跟随设备移动。(1秒1次定位)

            myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATE);

            break;

        case 3://连续定位、且将视角移动到地图中心点,地图依照设备方向旋转,定位点会跟随设备移动。(1秒1次定位)

            myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_MAP_ROTATE);

            break;

        case 4://连续定位、且将视角移动到地图中心点,定位点依照设备方向旋转,并且会跟随设备移动。(1秒1次定位)默认执行此种模式。

            myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE);

            break;

    }

    aMap.setMyLocationStyle(myLocationStyle);

}

//设置默认定位按钮是否显示,非必需设置。

public void showLocationButton(boolean isShow){

    aMap.getUiSettings().setMyLocationButtonEnabled(isShow);

}

// 设置为true表示启动显示定位蓝点,false表示隐藏定位蓝点并不进行定位,默认是false。

public void showLocationPoint(boolean isShow){

    aMap.setMyLocationEnabled(isShow);

}

public void setMapType(int type){

    switch (type){

        case 1:

            aMap.setMapType(AMap.MAP_TYPE_NORMAL);// 设置普通地图模式

            break;

        case 2:

            aMap.setMapType(AMap.MAP_TYPE_NAVI);// 设置导航地图模式

            break;

        case 3:

            aMap.setMapType(AMap.MAP_TYPE_NIGHT);// 设置夜景地图模式

            break;

        case 4:

            aMap.setMapType(AMap.MAP_TYPE_SATELLITE);// 设置卫星地图模式

            break;

    }

}

 public void onDestroy(){

    mapView.onDestroy();

 }

 public void onResume(){

     mapView.onResume();

 }

 public void onPause(){

     mapView.onPause();

 }

 public void onCreate(Bundle outState){

     mapView.onCreate(outState);

 }

 public void onSaveInstanceState(Bundle outState){

     mapView.onSaveInstanceState(outState);

 }

2、开发WXMapComponent组件

   新建WXMapComponent继承 WXComponent<WeexMapView>

   WXMapComponent.java代码如下:

   public class WXMapComponent extends WXComponent<WeexMapView> {

    WeexMapView mapView;

    WXSDKInstance wxInstance; //weex实例对象,用于获得上下文

    boolean clicked=false;

    //两个不同参数的构造方法

    public WXMapComponent(WXSDKInstance instance, WXDomObject dom, WXVContainer parent) {

        super(instance, dom, parent);

        wxInstance = instance;

    }

    public WXMapComponent(WXSDKInstance instance, WXDomObject dom, WXVContainer parent, int type) {

        super(instance, dom, parent, type);

        wxInstance = instance;

    }

    @Override

    protected WeexMapView initComponentHostView(@NonNull Context context) {

        //获得WeexMapView的对象

        this.mapView = new WeexMapView(context);

        return this.mapView;

    }

    @Override

    protected void onCreate() {

        super.onCreate();

    }

    @Override

    public void onActivityDestroy() {

        super.onActivityDestroy();

    }

    @WXComponentProp(name = "model")

    public void setMapModel(int model) {

       mapView.setMapModel(model);

    }

    //设置默认定位按钮是否显示,非必需设置。

    @WXComponentProp(name = "showLocationButton")

    public void showLocationButton(boolean isShow){

        mapView.showLocationButton(isShow);

    }

    // 设置为true表示启动显示定位蓝点,false表示隐藏定位蓝点并不进行定位,默认是false。

    @WXComponentProp(name = "showLocationPoint")

    public void showLocationPoint(boolean isShow)

    {

        mapView.showLocationPoint(isShow);

    }

    @WXComponentProp(name = "mapType")

    public void setMapType(int type){

        mapView.setMapType(type);

    }

    @JSMethod(uiThread = true)

    public void addMarker(float lnt, float lat, String title, String content,

                          boolean draggable, boolean setFlat, boolean isAnimation, long duration,

                          JSCallback clickCallback,JSCallback dragCallback) {

        LatLng latLng = new LatLng(lnt,lat);

        MarkerOptions markerOption = new MarkerOptions();

        markerOption.position(latLng);

        markerOption.title(title).snippet(content);

        markerOption.draggable(draggable);//设置Marker可拖动

        markerOption.icon(BitmapDescriptorFactory.fromBitmap(BitmapFactory

                .decodeResource(wxInstance.getContext().getResources(), R.drawable.cercle)));

        // 将Marker设置为贴地显示,可以双指下拉地图查看效果

        markerOption.setFlat(setFlat);//设置marker平贴地图效果

        Marker marker=mapView.getaMap().addMarker(markerOption);

        if(isAnimation){

            Animation animation = new RotateAnimation(marker.getRotateAngle(),marker.getRotateAngle()+180,0,0,0);

            animation.setDuration(duration);

            animation.setInterpolator(new LinearInterpolator());

            marker.setAnimation(animation);

            marker.startAnimation();

        }

        mapView.getaMap().setOnMarkerClickListener(new AMap.OnMarkerClickListener() {

            @Override

            public boolean onMarkerClick(Marker marker) {

                marker.showInfoWindow();

                return true;

            }

        });

        mapView.getaMap().setOnMarkerDragListener(new AMap.OnMarkerDragListener() {

            @Override

            public void onMarkerDragStart(Marker marker) {

            }

            @Override

            public void onMarkerDrag(Marker marker) {

            }

            @Override

            public void onMarkerDragEnd(Marker marker) {

            }

        });

    }

    @JSMethod(uiThread = true)

    public void addCircle(float lat,float lng,int radius,int strokeWidth){

     LatLng latLng=new LatLng(lat,lng);

     mapView.getaMap().addCircle(new CircleOptions().

             center(latLng).radius(radius).fillColor(Color.BLUE).

             strokeColor(Color.RED).strokeWidth(strokeWidth));

    }

    @JSMethod(uiThread = true)

    public void addLine(ArrayList list) throws JSONException {

        ArrayList<LatLng> latLngList=new ArrayList<LatLng>();

        for(int i=0;i<list.size();i++){

            com.alibaba.fastjson.JSONObject jsonObj=(com.alibaba.fastjson.JSONObject) list.get(i);

            BigDecimal bigLat= (BigDecimal) jsonObj.get("latitude");

            BigDecimal bigLng= (BigDecimal) jsonObj.get("longitude");

            float lat=bigLat.floatValue();

            float lng=bigLng.floatValue();

//            Log.d(lat+"-"+lng,"经纬度");

            LatLng latLng=new LatLng(lat,lng);

            latLngList.add(latLng);

        }

        mapView.getaMap().addPolyline(new PolylineOptions().addAll(latLngList).width(10).color(Color.BLUE));

    }

    @JSMethod(uiThread = true)

    public void addTileOverlay(ArrayList list){

        ArrayList<LatLng> latLngList=new ArrayList<LatLng>();

        for(int i=0;i<list.size();i++){

            com.alibaba.fastjson.JSONObject jsonObj=(com.alibaba.fastjson.JSONObject) list.get(i);

            BigDecimal bigLat= (BigDecimal) jsonObj.get("latitude");

            BigDecimal bigLng= (BigDecimal) jsonObj.get("longitude");

            float lat=bigLat.floatValue();

            float lng=bigLng.floatValue();

//            Log.d(lat+"-"+lng,"经纬度");

            LatLng latLng=new LatLng(lat,lng);

            latLngList.add(latLng);

        }

        // 构建热力图 HeatmapTileProvider

        HeatmapTileProvider.Builder builder = new HeatmapTileProvider.Builder();

        builder.data(latLngList); // 设置热力图绘制的数据

//                .gradient(A); // 设置热力图渐变,有默认值 DEFAULT_GRADIENT,可不设置该接口

// Gradient 的设置可见参考手册

// 构造热力图对象

        HeatmapTileProvider heatmapTileProvider = builder.build();

        // 初始化 TileOverlayOptions

        TileOverlayOptions tileOverlayOptions = new TileOverlayOptions();

        tileOverlayOptions.tileProvider(heatmapTileProvider); // 设置瓦片图层的提供者

// 向地图上添加 TileOverlayOptions 类对象

        mapView.getaMap().addTileOverlay(tileOverlayOptions);

    }

    @JSMethod(uiThread = true)

    public void setInfoWindowAdapter(){

      mapView.getaMap().setInfoWindowAdapter(new AMap.InfoWindowAdapter() {

          @Override

          public View getInfoWindow(Marker marker) {

              return null;

          }

          View infoWindow = null;

          @Override

          public View getInfoContents(Marker marker) {

              if(infoWindow == null) {

                  infoWindow = LayoutInflater.from(wxInstance.getContext()).inflate(

                          R.layout.custom_info_window, null);

              }

//              render(marker, infoWindow);

              return infoWindow;

           //加载custom_info_window.xml布局文件作为InfoWindow的样式

          }

      });

      mapView.getaMap().setOnInfoWindowClickListener(new AMap.OnInfoWindowClickListener() {

          @Override

          public void onInfoWindowClick(Marker marker) {

             String content=marker.getSnippet().toString();

              Toast.makeText(wxInstance.getContext(),content,Toast.LENGTH_LONG).show();

          }

      });

    }

}

   值得注意的一点是在H5界面的json数组通过组件的接口传到原生需要用ArrayList接收,在把ArrayList中的每一个元素转换成com.alibaba.fastjson.JSONObject。通过JSONObject的get("JsonName"),可以获得存在json中的值。

        for(int i=0;i<list.size();i++){

            com.alibaba.fastjson.JSONObject jsonObj=(com.alibaba.fastjson.JSONObject) list.get(i);

            BigDecimal bigLat= (BigDecimal) jsonObj.get("latitude");

            BigDecimal bigLng= (BigDecimal) jsonObj.get("longitude");

            float lat=bigLat.floatValue();

            float lng=bigLng.floatValue();

//            Log.d(lat+"-"+lng,"经纬度");

            LatLng latLng=new LatLng(lat,lng);

            latLngList.add(latLng);

        }

3、开发WXMapModule组件

 新建WXLocationModule 继承WXModule类,其中添加@JSMethod的方法可以在H5界面调用。

   public class WXLocationModule extends WXModule{

    @JSMethod

    public void getLocationInfo(float longitude,float latitude,final JSCallback callback) {

        GeocodeSearch geocoderSearch = new GeocodeSearch(mWXSDKInstance.getContext());//位置搜对象

        LatLonPoint point=new LatLonPoint(longitude,latitude);//坐标

        float range=200;//范围

        RegeocodeQuery query=new RegeocodeQuery(point,200,GeocodeSearch.AMAP);

        geocoderSearch.getFromLocationAsyn(query);

        geocoderSearch.setOnGeocodeSearchListener(new GeocodeSearch.OnGeocodeSearchListener() {

            @Override

            public void onRegeocodeSearched(RegeocodeResult regeocodeResult, int i) {//获得位置信息的回调方法

                Map<String, Object> map = new HashMap<>();

                map.put("locationInfo", regeocodeResult);

                callback.invokeAndKeepAlive(map);

            }

            @Override

            public void onGeocodeSearched(GeocodeResult geocodeResult, int i) {

            }

        });

    }

    @JSMethod

    public void getLocationByName(String name,String cityCode,final JSCallback callback){

        GeocodeSearch geocoderSearch = new GeocodeSearch(mWXSDKInstance.getContext());//位置搜对象

        // name表示地址,第二个参数表示查询城市,中文或者中文全拼,citycode、adcode

        GeocodeQuery query = new GeocodeQuery(name,cityCode);

        geocoderSearch.getFromLocationNameAsyn(query);

        geocoderSearch.setOnGeocodeSearchListener(new GeocodeSearch.OnGeocodeSearchListener() {

            @Override

            public void onRegeocodeSearched(RegeocodeResult regeocodeResult, int i) {

            }

            @Override

            public void onGeocodeSearched(GeocodeResult geocodeResult, int i) {

                Map<String, Object> map = new HashMap<>();

                map.put("location", geocodeResult);

                callback.invokeAndKeepAlive(map);

            }

        });

    }

    @JSMethod

    public void getWeatherInfo(String pace,String type){

    //检索参数为城市和天气类型,实况天气为WEATHER_TYPE_LIVE、天气预报为WEATHER_TYPE_FORECAST

    }

    @JSMethod

    public void getDistance(LatLng latLng1,LatLng latLng2){

        float distance = AMapUtils.calculateLineDistance(latLng1,latLng2);

    }

    @JSMethod

    public void downloadMapOffline(String cityname) throws AMapException {

//构造OfflineMapManager对象

            amapManager = new OfflineMapManager(mWXSDKInstance.getContext(), new OfflineMapManager.OfflineMapDownloadListener() {

            @Override

            public void onDownload(int i, int i1, String s) {

            }

            @Override

            public void onCheckUpdate(boolean b, String s) {

            }

            @Override

            public void onRemove(boolean b, String s, String s1) {

            }

        });

//按照citycode下载

//        amapManager.downloadByCityCode(String citycode);

//按照cityname下载

        amapManager.downloadByCityName(cityname);

//        amapManager.pause();

//        amapManager.stop();

        // 设置应用单独的地图存储目录

//        MapsInitializer.sdcardDir = "自定义的目录";

    }

    @JSMethod

    public void updateOfflineCityByName(String cityname) throws AMapException {

        //通过updateOfflineCityByName方法判断离线地图数据是否存在更新

        amapManager.updateOfflineCityByName(cityname);

    }

    public void deleteOfflineCityByName(String cityName){

        //删除某一城市的离线地图包

        amapManager.remove(cityName);

    }

    @JSMethod

    public void getDownloadOfflineMapCityList(){

//        获取城市列表

        ArrayList<OfflineMapCity> offlineMapCityList = amapManager.getOfflineMapCityList();

//        获取省列表

        ArrayList<OfflineMapProvince> offlineMapProvinceList = amapManager.getOfflineMapProvinceList();

//        获取已下载城市列表

        ArrayList<OfflineMapCity> downloadOfflineMapCityList = amapManager.getDownloadOfflineMapCityList();

//        获取正在或等待下载城市列表

        ArrayList<OfflineMapCity> downloadingCityList = amapManager.getDownloadingCityList();

    }

}

4、注册Component和Module

在新建myAplication继承Application,在其onCreate()方法中注册组件。

Weex地图组件开发流程及使用(android)

三、组件主要功能及使用方法

1)WXlocationModule使用

  在H5中引入组件:

  var location=weex.requireModule('Location');

1、根据描述和城市编码获得坐标信息

location.getLocationByName('廊坊市广阳区新奥科技园B座','0316',function (res) {

     self.point=res.location.geocodeAddressList[0].latLonPoint;//获得坐标信息

    });

2、根据坐标获得位置信息

  location.getLocationInfo(lat,lnt,function (res) {

    var info=res;

   });

3、获得天气信息

  location.getWeatherInfo('北京市','now',function (res) {

    var weatherInfo=res;

  });

4、得到两个坐标点之间的距离

 location.getDistance(latLng1,latLng2,function (res) {

    var distance=res;

 });

5、离线地图相关

location.downloadMapOffline(cityname);//下载离线地图,可设置下载路径

  location.deleteOfflineCityByName(cityName);//删除离线地图

  location.getDownloadOfflineMapCityList()//获得离线地图列表

2)WXMapComponent使用

   在H5中使用组件:

  <map ref="myMap" style="width: 750px;height: 1300px" showLocationButton="true" model="1" showLocationPoint="true" mapType="1">

</map>

 showLocationButton:是否显示定位按钮

    Model:定位方式

    mapType:地图模式(卫星图,夜间图等)

showLocationPoint:是否显示当前所在点的标示图

1、显示地图上某个坐标处的标示,点击显示提示信息

   this.$refs.myMap.addMarker(lat, lnt, '新奥科技园', '新奥科技园B座',

    true, false, true, 1.00,      //参数:经度、纬度、标题、内容、是否可拖动、是否平贴地图、是否使用动画、动画时间

    function (res) {//点击事件

     modal.toast({message:'click'})

    },function (res) {//拖动事件

      modal.toast({message:'drag'})

    });

2、以某个坐标点为圆心,画一个圆形图

self.$refs.myMap.addCircle(self.point.latitude,self.point.longitude,1000,20);

     第一个和第二个参数分别为圆心的经度和纬度坐标,第三个参数为半径,第四个参数为圆形的线的宽度

3、在地图上绘制线

   self.$refs.myMap.addLine(self.pointList);

   参数是一个坐标点的集合

4、在地图上绘制热力图层

   self.$refs.myMap.addTileOverlay(self.pointList);

    参数是一个坐标的集合

继续阅读