几行代码实现高德地图的高级用法

前段时间搞高德地图,集成地图后,发现如果把地图这块放在view里面,不便于后期的维护,想着封装一个,把地图有关的方法,专门放一个类,同时也方便以后的偷懒☺.Let's Go!
  • 显示地图
public class MapActivity extends AppCompatActivity {
    @InjectView(R.id.mapView)
    MapView mMapView;
    private AMap aMap;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_map);
        // 使用黄油刀注解找控件
        ButterKnife.inject(this);
        initMap(savedInstanceState);
    }

    private void initMap(Bundle savedInstanceState) {
        mMapView.onCreate(savedInstanceState);
        aMap = null;
        if (aMap == null) {
            aMap = mMapView.getMap();
        }
        // 显示地图
        MapUtil.getInstance().initMap(aMap, this);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        // 在activity执行onDestroy时执行mMapView.onDestroy(),销毁地图
        mMapView.onDestroy();
    }

    @Override
    public void onResume() {
        super.onResume();
        // 在activity执行onResume时执行mMapView.onResume (),重新绘制加载地图
        mMapView.onResume();
    }


    @Override
    public void onPause() {
        super.onPause();
        // 在activity执行onPause时执行mMapView.onPause (),暂停地图的绘制
        mMapView.onPause();
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        // 在activity执行onSaveInstanceState时执行mMapView.onSaveInstanceState (outState),保存地图当前的状态
        mMapView.onSaveInstanceState(outState);
    }

}
除了地图相关的配置外,你只需要 MapUtil.getInstance().initMap(aMap, this);一行代码就可以实现,够简洁吧!下面我们看下,内部的实现
    // 单例没啥好说的 
    private static MapUtil sMapUtil;
    private LatLng  mLatLng;

    private MapUtil() {

    }
![![微信图片_20180519135100.jpg](https://upload-images.jianshu.io/upload_images/5286943-34dfb6ace9ea966b.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
](https://upload-images.jianshu.io/upload_images/5286943-5ea74273e21ca41f.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

    public static MapUtil getInstance() {
        if (sMapUtil == null) {
            synchronized (MapUtil.class) {
                if (sMapUtil == null) {
                    sMapUtil = new MapUtil();
                }
            }
        }
        return sMapUtil;
    }

    // 初始化地图,关键代码
    public MapUtil initMap(AMap aMap, Context context) {
        this.aMap = aMap;
        this.mContext = context;
        mlocationClient = new AMapLocationClient(context);
        //初始化定位参数
        mLocationOption = new AMapLocationClientOption();
        //设置定位监听
        mlocationClient.setLocationListener(this);
        //设置定位模式为高精度模式,Battery_Saving为低功耗模式,Device_Sensors是仅设备模式
        mLocationOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);
        //设置定位间隔,单位毫秒,默认为2000ms
        mLocationOption.setInterval(3000);
        //设置定位参数
        mlocationClient.setLocationOption(mLocationOption);
        // 此方法为每隔固定时间会发起一次定位请求,为了减少电量消耗或网络流量消耗,
        // 注意设置合适的定位时间的间隔(最小间隔支持为1000ms),并且在合适时间调用stopLocation()方法来取消定位请求
        // 在定位结束后,在合适的生命周期调用onDestroy()方法
        // 在单次定位情况下,定位无论成功与否,都无需调用stopLocation()方法移除请求,定位sdk内部会移除
        //启动定位
        mlocationClient.startLocation();
        // TODO: 2018/5/13 地图的层级大小,可以对外暴露 
        aMap.moveCamera(CameraUpdateFactory.zoomTo(19));
        // 显示定位蓝点
        initPoint();
        // 去掉右边缩放按钮
        aMap.getUiSettings().setZoomControlsEnabled(false);
        aMap.setOnCameraChangeListener(this);
        return this;
    }

// 自定义定位蓝点
    public void initPoint() {
        MyLocationStyle myLocationStyle;
        myLocationStyle = new MyLocationStyle();//初始化定位蓝点样式类myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE);//连续定位、且将视角移动到地图中心点,定位点依照设备方向旋转,并且会跟随设备移动。(1秒1次定位)如果不设置myLocationType,默认也会执行此种模式。
        myLocationStyle.interval(2000); //设置连续定位模式下的定位间隔,只在连续定位模式下生效,单次定位模式下不会生效。单位为毫秒。
        // 设置边框的颜色
        myLocationStyle.strokeColor(Color.TRANSPARENT);
        // 设置边框的填充色
        myLocationStyle.radiusFillColor(Color.TRANSPARENT);
        // 设置定位点图片
        myLocationStyle.myLocationIcon(getBitmapDescriptor(R.mipmap.icon_location_blue));
        // 定位一次,且将视角移动到地图中心点
        myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE_NO_CENTER);
        aMap.setMyLocationStyle(myLocationStyle);//设置定位蓝点的Style
        //aMap.getUiSettings().setMyLocationButtonEnabled(true);设置默认定位按钮是否显示,非必需设置。
        aMap.setMyLocationEnabled(true);// 设置为true表示启动显示定位蓝点,false表示隐藏定位蓝点并不进行定位,默认是false。
        // 因为模式问题,所以要手动调用
        if (mLatLng != null) {
            aMap.moveCamera(CameraUpdateFactory.changeLatLng(mLatLng));
        }
    }
  • 绘制Marker点
private void initMap(Bundle savedInstanceState) {
        mMapView.onCreate(savedInstanceState);
        aMap = null;
        if (aMap == null) {
            aMap = mMapView.getMap();
        }
        // 显示地图,设置地图回调
        MapUtil.getInstance().initMap(aMap, this).setMapRefreshListener(this);
    }

    public void drawMarker(LatLng latLng) {
        // 模拟数据集合
        List<LatLng> markerList = new ArrayList<>();
        for (int i = 0; i < 4; i++) {
            double longitude = latLng.longitude + ((i + 1) * 0.0001);
            double latitude = latLng.latitude + ((i + 1) * 0.0001);
            markerList.add(new LatLng(latitude, longitude));
        }
        // 绘制Marker集合
        MapUtil.getInstance().addAllMarker(markerList);
        // 绘制Marker点
        MapUtil.getInstance().addMarker(latLng);
    }

    /**
     * 得到经纬度
     * @param latLng
     */
    @Override
    public void getLatLng(LatLng latLng) {
        // 绘制marker
        drawMarker(latLng);
    }

MapUtil

 public void addAllMarker(List<LatLng> latLngList) {
        for (LatLng latLng : latLngList) {
            addMarker(latLng);
        }
    }

    public void addMarker(LatLng latLng) {
        MarkerOptions markerOptions = new MarkerOptions();
        markerOptions.position(latLng);
        // TODO: 2018/5/13 如果是复杂的,可以把布局转成bitmap
        //        View view = View.inflate(mContext, R.layout.marker, null);
        //        Bitmap bitmap = convertViewToBitmap(view);

        // 自定义图片
        markerOptions.icon(BitmapDescriptorFactory.fromBitmap(BitmapFactory
                .decodeResource(mContext.getResources(), R.mipmap.icon_taskcar_get)));
        //        markerOptions.icon(BitmapDescriptorFactory.fromBitmap(bitmap));

        Marker marker = aMap.addMarker(markerOptions);
        mMarkerSparseArray.put(mMarkerSparseArray.size(), marker);
        marker.showInfoWindow();
        // 是否需要显示弹窗
        infoWindow();
    }

  • Marker点的点击事件
我就是怎么强大
// 由于第一次点击也会走地图的回调,所以要加个开关
    private boolean toggle = false;

    // 定义 Marker [图片上传中...(31bcedde8ed5d0abf39d165177c83736.gif-b70360-1526708414566-0)]
点击事件监听
    AMap.OnMarkerClickListener markerClickListener = new AMap.OnMarkerClickListener() {
        // marker 对象被点击时回调的接口
        // 返回 true 则表示接口已响应事件,否则返回false
        @Override
        public boolean onMarkerClick(Marker marker) {
            mMarker = marker;
            toggle = true;
            MapUtil.getInstance().addInfoWindow(marker);
            return false;
        }
    };

 private void initMap(Bundle savedInstanceState) {
        mMapView.onCreate(savedInstanceState);
        // 使用黄油刀注解找控件
        aMap = null;
        if (aMap == null) {
            aMap = mMapView.getMap();
        }
        // 显示地图,设置地图回调
        MapUtil.getInstance().initMap(aMap, this).setMapRefreshListener(this);
        // 实现地图的监听
        aMap.setOnMapClickListener(new AMap.OnMapClickListener() {
            @Override
            public void onMapClick(LatLng latLng) {
                if (!toggle && mMarker != null) {
                    MapUtil.getInstance().removeInfoWindow(mMarker);
                    mMarker = null;
                }
                toggle = false;
            }
        });
        // 实现marker的监听
        aMap.setOnMarkerClickListener(markerClickListener);
    }

MapUtil

/**
     * 添加移除infoWindow
     * @param marker
     */
    public void addInfoWindow(Marker marker) {
        marker.setInfoWindowEnable(true);
    }

    /**
     * 移除infoWindow
     * @param marker
     */
    public void removeInfoWindow(Marker marker) {
        marker.setInfoWindowEnable(false);
    }
绘制矩形
 /**
     * 得到经纬度
     *
     * @param latLng
     */
    @Override
    public void getLatLng(LatLng latLng) {
        // 绘制marker
        drawMarker(latLng);
        // 绘制线
        drawRectangle(latLng);
    }

 private void drawRectangle(LatLng latLng) {
        MapUtil.getInstance().addRectangle(latLng);
    }

MapUtil

public void addRectangle(LatLng latLng) {
        // 绘制一个长方形
        aMap.addPolygon(new PolygonOptions()
                .addAll(createRectangle(latLng, 0.0001, 0.0001))
                .fillColor(Color.parseColor("#FFCBCB"))
                // 线的宽度取消
                .strokeWidth(0)
        );
        // 虚线组成一个长方形
        aMap.addPolyline(new PolylineOptions()
                .addAll(createRectangle(latLng, 0.0001, 0.0001))
                .width(10)
                .setDottedLine(true)
                .color(Color.parseColor("#F45A5A")));
    }

    public void addRectangle(List<LatLng> latLngList) {
        // 绘制一个长方形
        aMap.addPolygon(new PolygonOptions()
                .addAll(latLngList)
                .fillColor(Color.parseColor("#4DBDEDFF"))
                // 线的宽度取消
                .strokeWidth(0)
        );
        // 虚线组成一个长方形
        aMap.addPolyline(new PolylineOptions()
                .addAll(latLngList)
                .width(10)
                .setDottedLine(true)
                .color(Color.parseColor("#3BC3F5")));
    }

    /**
     * 生成一个长方形的四个坐标点
     */
    private List<LatLng> createRectangle(LatLng center, double halfWidth, double halfHeight) {
        List<LatLng> latLngs = new ArrayList<LatLng>();
        // TODO: 2018/5/19 添加最后一个点,组成闭合,不然会少一边 
        latLngs.add(new LatLng(center.latitude + halfHeight, center.longitude - halfWidth));
        // 矩形的四个点
        latLngs.add(new LatLng(center.latitude - halfHeight, center.longitude - halfWidth));
        latLngs.add(new LatLng(center.latitude - halfHeight, center.longitude + halfWidth));
        latLngs.add(new LatLng(center.latitude + halfHeight, center.longitude + halfWidth));
        latLngs.add(new LatLng(center.latitude + halfHeight, center.longitude - halfWidth));
        return latLngs;
    }
这里要注意:画矩形要给5个点,第一个和最后一个点一样,文档上是4个点,会少一边
移动指定距离刷新地图
@Override
    public void onCameraChange(CameraPosition cameraPosition) {

    }

    @Override
    public void onCameraChangeFinish(CameraPosition cameraPosition) {
        LatLng currentLatlng = cameraPosition.target;
        double distance = AMapUtils.calculateLineDistance(preLatlng, currentLatlng);
        totalDistance = distance;
        Log.d(TAG, "onCameraChange: 距离" + totalDistance);
        if (totalDistance >= REFRESH_DISTANCE) {
            if (firstChange) {
                firstChange = false;
                return;
            }
            preLatlng = currentLatlng;
            Log.d(TAG, "onCameraChange: 要刷新了");
            totalDistance = 0;
            if (mMapListener != null) {
                mMapListener.refresh();
            }
        }
    }
监听地图中心点的位置,和起始点位置,获取距离,如果大于,就把当前点记录,这里要注意的是,刚开始的时候位置会偏移很大,排除第一次的
  • 重置指南针
image

MapActivity没什么好说的

@OnClick(R.id.iv_location)
    public void onViewClicked() {
        MapUtil.getInstance().initPoint();
    }

MapUtil

// 开启指南针
// 初始化地图,关键代码
    public MapUtil initMap(AMap aMap, Context context, int getZoomB) {
        this.aMap = aMap;
        this.mContext = context;
        mlocationClient = new AMapLocationClient(context);
        //初始化定位参数
        mLocationOption = new AMapLocationClientOption();
        //设置定位监听
        mlocationClient.setLocationListener(this);
        //设置定位模式为高精度模式,Battery_Saving为低功耗模式,Device_Sensors是仅设备模式
        mLocationOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);
        //设置定位间隔,单位毫秒,默认为2000ms
        mLocationOption.setInterval(3000);
        //设置定位参数
        mlocationClient.setLocationOption(mLocationOption);
        // 此方法为每隔固定时间会发起一次定位请求,为了减少电量消耗或网络流量消耗,
        // 注意设置合适的定位时间的间隔(最小间隔支持为1000ms),并且在合适时间调用stopLocation()方法来取消定位请求
        // 在定位结束后,在合适的生命周期调用onDestroy()方法
        // 在单次定位情况下,定位无论成功与否,都无需调用stopLocation()方法移除请求,定位sdk内部会移除
        //启动定位
        mlocationClient.startLocation();
        // 显示定位蓝点
        initPoint();
        // 去掉右边缩放按钮
        aMap.getUiSettings().setZoomControlsEnabled(false);
        aMap.setOnCameraChangeListener(this);
        // 开启指南针
        aMap.getUiSettings().setCompassEnabled(true);
        return this;
    }

 // 自定义定位蓝点
    public void initPoint() {
        MyLocationStyle myLocationStyle;
        myLocationStyle = new MyLocationStyle();//初始化定位蓝点样式类myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE);//连续定位、且将视角移动到地图中心点,定位点依照设备方向旋转,并且会跟随设备移动。(1秒1次定位)如果不设置myLocationType,默认也会执行此种模式。
        myLocationStyle.interval(2000); //设置连续定位模式下的定位间隔,只在连续定位模式下生效,单次定位模式下不会生效。单位为毫秒。
        // 设置边框的颜色
        myLocationStyle.strokeColor(Color.TRANSPARENT);
        // 设置边框的填充色
        myLocationStyle.radiusFillColor(Color.TRANSPARENT);
        // 设置定位点图片
        myLocationStyle.myLocationIcon(getBitmapDescriptor(R.mipmap.icon_location_blue));
        // 定位一次,且将视角移动到地图中心点
        myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE_NO_CENTER);
        aMap.setMyLocationStyle(myLocationStyle);//设置定位蓝点的Style
        //aMap.getUiSettings().setMyLocationButtonEnabled(true);设置默认定位按钮是否显示,非必需设置。
        aMap.setMyLocationEnabled(true);// 设置为true表示启动显示定位蓝点,false表示隐藏定位蓝点并不进行定位,默认是false。
        // 因为模式问题,所以要手动调用
        if (mLatLng != null) {
            aMap.moveCamera(CameraUpdateFactory.changeLatLng(mLatLng));
        }
        // 地图的层级大小
        aMap.moveCamera(CameraUpdateFactory.zoomTo(getZoomB));
        // TODO: 2018/5/21 0021  重置指南针位置,找了好久
        if (mLatLng != null) {
            float bearing = 0.0f;  // 地图默认方向
            float tilt = 0.0f;  // 地图默认方向
            aMap.animateCamera(CameraUpdateFactory.newCameraPosition(new CameraPosition(mLatLng, getZoomB, tilt, bearing)));
        }
    }

文末:主要提供一种思路,如果有不对或者可以改进的,欢迎下方留言

百度网盘地址:https://pan.baidu.com/s/1KiCA5y9FhxPxPMQObD9SQg

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,732评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,496评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,264评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,807评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,806评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,675评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,029评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,683评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,704评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,666评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,773评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,413评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,016评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,204评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,083评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,503评论 2 343

推荐阅读更多精彩内容