Android 天气APP(二十四)地图天气(上)自动定位和地图点击定位(2)

private LocationClient mLocationClient;//定位

private BaiduMap mBaiduMap;//百度地图

/**

  • 定位SDK监听,

*/

private class MyLocationListener implements BDLocationListener {

/**

  • 监听返回数据 MapView 销毁后不在处理新接收的位置

  • @param bdLocation 定位信息

*/

@Override

public void onReceiveLocation(BDLocation bdLocation) {

if (bdLocation == null || mapView == null) {//做null处理,避免APP崩溃

return;

}

MyLocationData locationData = new MyLocationData.Builder()//定位构造器

.accuracy(bdLocation.getRadius())//设置定位数据的精度信息,单位:米

.direction(bdLocation.getDirection())//设置定位数据的方向信息

.latitude(bdLocation.getLatitude())//设置定位数据的纬度

.longitude(bdLocation.getLongitude())//设置定位数据的经度

.build();//构建生成定位数据对象

mBaiduMap.setMyLocationData(locationData);//设置定位数据,只有开启定位图层之后才会生效

//创建一个经纬度构造对象,传入定位返回的经纬度,Latitude是纬度,Longitude是经度,一对经纬度值代表地球上一个地点。

LatLng latLng = new LatLng(bdLocation.getLatitude(),bdLocation.getLongitude());

MapStatus.Builder builder = new MapStatus.Builder()//创建地图状态构造器

.target(latLng)//设置地图中心点,传入经纬度对象

.zoom(13.0f);//设置地图缩放级别 13 表示 比例尺/2000米 2公里

//改变地图状态,使用地图状态更新工厂中的新地图状态方法,传入状态构造器

mBaiduMap.animateMapStatus(MapStatusUpdateFactory.newMapStatus(builder.build()));

}

}

注释都是代码里,应该够清楚了吧,官方接入文档都没有我这个清楚。

然后再写一个初始化定位的方法。

/**

  • 初始化定位

*/

private void initLocation() {

mBaiduMap.setMyLocationEnabled(true);//开启定位图层

mLocationClient = new LocationClient(context);//定位初始化

MyLocationListener listener = new MyLocationListener();//创建定位监听器

mLocationClient.registerLocationListener(listener);//注册定位监听,否则监听无效

LocationClientOption option = new LocationClientOption();//创建定位设置

option.setOpenGps(true);//打开GPS

option.setCoorType(“bd09ll”);//设置坐标类型 可以设置BD09LL和GCJ02两种坐标

option.setScanSpan(0);//设置扫描间隔,单位是毫秒,0 则表示只定位一次,设置毫秒不能低于1000,也就是1秒

mLocationClient.setLocOption(option);//传入定位设置

mLocationClient.start();//开始定位

}

在这个方法中,对定位做了监听和设置,然后启动定位。

最后只要在initData方法中调用就可以了。

在这里插入图片描述

最后就是关于Activity的生命周期要对地图做相应的处理。代码如下:

@Override

protected void onResume() {

super.onResume();

mapView.onResume();//生命周期管理

}

@Override

protected void onPause() {

super.onPause();

mapView.onPause();//生命周期管理

}

@Override

protected void onDestroy() {

super.onDestroy();

mLocationClient.stop();// 退出时销毁定位

mBaiduMap.setMyLocationEnabled(false);// 关闭定位图层

mapView.onDestroy();// 在activity执行onDestroy时必须调用mMapView.onDestroy()

}

然后就可以运行了,运行看看吧。

在这里插入图片描述

可以看到定位还是蛮准的,定位时间取决于你的网速。当然如果你想要地址显示的更精确一些的话,可以修改

在这里插入图片描述

可以参照这个表来进行设置

| 显示层级 | 比例尺/米 | 比例尺/公里 |

| — | — | — |

| 4 | 1000000 | 1000 |

| 5 | 500000 | 500 |

| 6 | 200000 | 200 |

| 7 | 100000 | 100 |

| 8 | 50000 | 50 |

| 9 | 25000 | 25 |

| 10 | 20000 | 20 |

| 11 | 10000 | 10 |

| 12 | 5000 | 5 |

| 13 | 2000 | 2 |

| 14 | 1000 | 1 |

| 15 | 500 | 0.5 |

| 16 | 200 | 0.2 |

| 17 | 100 | 0.1 |

| 18 | 50 | 0.05 |

| 19 | 20 | 0.02 |

| 20 | 10 | 0.01 |

| 21 | 5 | 0.005 |

比如说我设置成4层级的

zoom(4.0f)

运行一下:

在这里插入图片描述

根据自己的需求来就行了。所以我设置的是13,大概就能看清楚附近的区/县就可以了,因为和风天气API请求的最低单位就是区/县。

四、点击地图定位


当然光是一个当前定位是不足以满足用户的,用户一般是都是想点那里就点那里,你点了没反应就是你的软件有问题,然后直接给你卸载,你哭都没地方哭去。下面来看看具体实现吧。

先声明需要的变量

private Marker marker;//标点也可以说是覆盖物

private BitmapDescriptor bitmap;//标点的图标

private double markerLatitude = 0;//标点纬度

private double markerLongitude = 0;//标点经度

private double latitude;//定位纬度

private double longitude;//定位经度

刚才都说了是点击地图定位,那么肯定就需要一个点击事件对吧。当然这个事件肯定不是常规的View.OnClickListener,而是百度地图已经封装好的点击方法。

/**

  • 初始化地图点击

*/

private void initMapOnClick() {

mBaiduMap.setOnMapClickListener(new BaiduMap.OnMapClickListener() {

//地图内 Poi 单击事件回调函数 那么poi是什么呢?你可以当做兴趣点,

// 比如我想知道我当前所在地有那些餐厅,那么餐厅就是poi,

// 而你点击这个poi就会拿到详情的信息数据,当然不在我的业务需求之内,所以只做解释

@Override

public void onMapPoiClick(MapPoi mapPoi) {

}

//地图单击事件回调函数

@Override

public void onMapClick(LatLng latLng) {

}

});

}

这里添加一个标点marker的图标

在这里插入图片描述

可以看到要实现两个构造方法,而我只需要在onMapClick下处理点击之后的业务逻辑就可以了。

//地图单击事件回调函数

@Override

public void onMapClick(LatLng latLng) {

bitmap = BitmapDescriptorFactory.fromResource(R.mipmap.icon_marka);// 设置marker图标

//通过LatLng获取经纬度

markerLatitude = latLng.latitude;//获取纬度

markerLongitude = latLng.longitude;//获取经度

mBaiduMap.clear();//清除之前的图层

MarkerOptions options = new MarkerOptions()//创建标点marker设置对象

.position(latLng)//设置标点的定位

.icon(bitmap);//设置标点图标

marker = (Marker) mBaiduMap.addOverlay(options);//在地图上显示标点

//点击地图之后重新定位

initLocation();

}

当点击地图时,或者经纬度,然后清除当前的图层,再配置标点的坐标和图标,然后添加到地图上,这时候重新定位一下,定位到标点的这个地方,所以要在监听的回调里面中修改原来的代码

在这里插入图片描述

在拿到定位监听到之后首先判断是自动定位,还是点击地图定位。因为如果你点了地图,那么markerLatitude就不会是为0的,因为我在点击地图的时候给markerLatitude赋了值,作为判断条件区分你是自动还是手动。然后赋值给一个全局的经纬度变量,再把这个变量放到定位数据里,再设置成地图中心坐标,最后渲染出来,就可以做到,我点那里就定位到哪里了,指哪打哪。OK,没有效果图那就是扯淡,运行一下:

在这里插入图片描述

效果还是不错滴!但是我又想回到原来的位置呢?

Wath!!!!

五、回到当前位置并清除标点


先来说一下实现的业务逻辑,当我一进入这个页面时,是自动定位的,这是要隐藏自动定位按钮,当我点击定位按钮时,清除标点回到当前定位地址。这个按钮我打算用浮动按钮来做,因为它隐藏和显示的时候会自带动画效果,相当不错。

在build.gradle中添加,有就不用了,然后Sync,否则你找不到这个控件。

implementation ‘com.google.android.material:material:1.0.0’

简单修改activity_map_weather.xml

<com.google.android.material.floatingactionbutton.FloatingActionButton

android:id=“@+id/btn_auto_location”

android:layout_width=“wrap_content”

android:layout_height=“wrap_content”

android:layout_gravity=“bottom”

android:layout_marginLeft=“@dimen/dp_50”

android:layout_marginBottom=“@dimen/dp_10”

android:clickable=“true”

android:src=“@mipmap/icon_auto_location”

app:backgroundTint=“@color/transparent_bg_3”

app:backgroundTintMode=“screen”

app:borderWidth=“@dimen/dp_0”

app:fabSize=“mini”

app:hoveredFocusedTranslationZ=“@dimen/dp_18”

app:pressedTranslationZ=“@dimen/dp_18”

app:rippleColor=“@color/blue_one” />

这个按钮会显示在页面的左下角比例尺的左边。

icon_auto_location.png如下,其他的参数都是常规数据,背景颜色尺寸一些都是可以自己写的。

在这里插入图片描述

然后回到MapWeatherActivity

@BindView(R.id.btn_auto_location)

FloatingActionButton btnAutoLocation;//重新定位按钮

然后在点击的时候重置标点的经纬度参数值,清除标点,再重新定位

/**

  • 点击事件

*/

@OnClick(R.id.btn_auto_location)

public void onViewClicked() {

markerLatitude = 0;

markerLongitude = 0;

marker.remove();//清除标点

initLocation();

}

在定位成功的回调中对定位按钮进行显示和隐藏的控制。

在这里插入图片描述

然后在新建一个initView方法,放入进入页面的一些基本配置。

在这里插入图片描述

OK,运行一下。

在这里插入图片描述

六、根据经纬度获取实际的定位信息


我们已经拿到经纬度信息了,那么这个信息需要转换为实际的位置,否则别人也不知道你定位在哪里,那就没有什么意义了。

先声明地址解析

private GeoCoder geoCoder;//百度地址解析

然后创建一个地址解析结果监听器

/**

  • 编码结果监听

*/

private OnGetGeoCoderResultListener onGetGeoCoderResultListener = new OnGetGeoCoderResultListener() {

/**

  • 编码结果返回 就是通过具体位置信息获取坐标

  • @param geoCodeResult 编码返回结果

*/

@Override

public void onGetGeoCodeResult(GeoCodeResult geoCodeResult) {

}

/**

  • 反编码结果返回 就是通过坐标获取具体位置信息

  • @param reverseGeoCodeResult 反编码返回结果

*/

@Override

public void onGetReverseGeoCodeResult(ReverseGeoCodeResult reverseGeoCodeResult) {

if (reverseGeoCodeResult == null

|| reverseGeoCodeResult.error != SearchResult.ERRORNO.NO_ERROR) {

// 没有检测到结果

return;

}

ReverseGeoCodeResult.AddressComponent addressDetail = reverseGeoCodeResult.getAddressDetail();

//需要的地址信息就在AddressComponent 里

学习分享

在当下这个信息共享的时代,很多资源都可以在网络上找到,只取决于你愿不愿意找或是找的方法对不对了

很多朋友不是没有资料,大多都是有几十上百个G,但是杂乱无章,不知道怎么看从哪看起,甚至是看后就忘

如果大家觉得自己在网上找的资料非常杂乱、不成体系的话,我也分享一套给大家,比较系统,我平常自己也会经常研读。

2021最新上万页的大厂面试真题

七大模块学习资料:如NDK模块开发、Android框架体系架构…

只有系统,有方向的学习,才能在段时间内迅速提高自己的技术。

这份体系学习笔记,适应人群:
第一,学习知识比较碎片化,没有合理的学习路线与进阶方向。
第二,开发几年,不知道如何进阶更进一步,比较迷茫。
第三,到了合适的年纪,后续不知道该如何发展,转型管理,还是加强技术研究。如果你有需要,我这里恰好有为什么,不来领取!说不定能改变你现在的状态呢!
由于文章内容比较多,篇幅不允许,部分未展示内容以截图方式展示 。

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

料非常杂乱、不成体系的话,我也分享一套给大家,比较系统,我平常自己也会经常研读。

2021最新上万页的大厂面试真题

[外链图片转存中…(img-J2r05xuO-1714310535419)]

七大模块学习资料:如NDK模块开发、Android框架体系架构…

[外链图片转存中…(img-llVkphQV-1714310535420)]

只有系统,有方向的学习,才能在段时间内迅速提高自己的技术。

这份体系学习笔记,适应人群:
第一,学习知识比较碎片化,没有合理的学习路线与进阶方向。
第二,开发几年,不知道如何进阶更进一步,比较迷茫。
第三,到了合适的年纪,后续不知道该如何发展,转型管理,还是加强技术研究。如果你有需要,我这里恰好有为什么,不来领取!说不定能改变你现在的状态呢!
由于文章内容比较多,篇幅不允许,部分未展示内容以截图方式展示 。

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 28
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值