android 仿京东地址选择_Android 开发:仿美团地址选择

本文介绍如何在Android应用中集成百度地图API,实现地图展示、用户定位以及搜索周边POI功能。通过逆地理编码获取滑动地图时的POI信息,同时在搜索框中使用关键词进行POI检索,展示距离用户最近的地点。详细步骤包括初始化地图、获取用户位置、移动地图至用户位置以及处理滑动和搜索事件。
摘要由CSDN通过智能技术生成
67b22b688ea21c481bb2c62ccc0fd318.png

最近做了这个功能,分享一下,用的是百度地图api,和美团外卖的地址选择界面差不多,也就是可以搜索或者滑动地图展示地址列表给用户选择,看下效果图先。

58f28bbacfa7e1c40d7e74e6c47816e4.gif

文章重点

12cc25fa7db6b2cc29e45df122edc94d.png
  1. 展示地图并定位到“我”的位置
  2. 滑动地图获取周边poi(逆地理编码)
  3. 搜索框输入查询poi(POI检索)

前言

这里先提一下,我们要选择的地址信息其实是POI(Point of Interest),即“兴趣点”。在地理信息系统中,一个POI可以是一栋房子、一个景点、一个邮筒或者一个公交站等。百度地图SDK提供三种类型的POI检索:城市内检索、周边检索和区域检索(即矩形区域检索)。这里我就不详细介绍了,具体请查看百度地图开发文档(http://lbsyun.baidu.com/index.php?title=androidsdk)。

需求分析

ed8d706174088d9ca42e457a7ed461af.png

我们要实现的功能主要包括两个操作:滑动地图和搜索框搜索。

  • 滑动地图:滑动地图主要是获取滑动后地图中心点坐标,然后获取poi信息,但是这里不能用上面提到的三种POI检索方式,POI检索都需要传入关键字(不能为空),而我们仅仅只是滑动地图,所以需要用另外一种方式:逆地理编码检索。使用逆地理编码检索时,可以通过检索结果ReverseGeoCodeResult类的getPoiList()方法获取传入位置周围的POI信息。
  • 搜索框搜索:这里就可以使用百度地图SDK提供的三种POI检索方式来进行检索,同时为了方便查看,还可以计算出每个POI和用户之间的距离。

一、展示地图并定位到“我”的位置

1.展示地图

展示地图非常简单,首先需要调用SDKInitializer.initialize()方法来进行初始化操作,它接收一个全局的Context参数,记得初始化操作一定要在setContentView()方法前调用(可以到application中进行初始化),然后调用findViewById()方法获取MapView实例,最后记得要对MapView进行资源释放。

2.移动到我的位置

2.1 获取我的位置

首先要确定自己的位置,代码如下所示:

public class MainActivity extends AppCompatActivity implements OnGetPoiSearchResultListener { private MyLocationListener myListener = new MyLocationListener(); public LocationClient mLocationClient = null; private LocationClientOption option = null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initLocation(); } /** * 初始化定位相关 */ private void initLocation() { // 声明LocationClient类 mLocationClient = new LocationClient(getApplicationContext()); mLocationClient.setLocOption(option); // 注册监听函数 mLocationClient.registerLocationListener(myListener); mLocationClient.start(); } /** * 监听当前位置 */ public class MyLocationListener extends BDAbstractLocationListener { @Override public void onReceiveLocation(BDLocation location) { //mapView 销毁后不在处理新接收的位置 if (location == null || mMapView == null) { return; } if (location.getLocType() == BDLocation.TypeGpsLocation || location.getLocType() == BDLocation.TypeNetWorkLocation) { Log.e(TAG, "当前“我”的位置:" + location.getAddrStr()); navigateTo(location); } } }}

可以看到,我们首先创建LocationClient实例,然后调用LocationClient的registerLocationListener()方法来注册一个定位监听器,当获取到位置信息的时候,就会回调这个定位监听器。开启定位很简单,只需要调用一下LocationClient的start()方法就可以了。

定位的结果会回调到监听器中,也就是MyLocationListener,在onReceiveLocation()方法中即可通过BDLocation对象获取相关位置详细信息。

注:定位属于危险权限,所以要动态权限申请,记得不要忘记了。

2.2 移动到我的位置

获取到定位后就需要将地图中心点移动到当前位置,代码如下:

 private boolean isFirstLocation = true; /** * 根据获取到的位置在地图上移动“我”的位置 * * @param location */ private void navigateTo(BDLocation location) { double longitude = location.getLongitude(); double latitude = location.getLatitude(); if (isFirstLocation) { currentLatLng = new LatLng(latitude, longitude); MapStatus.Builder builder = new MapStatus.Builder(); MapStatus mapStatus = builder.target(currentLatLng).zoom(17.0f).build(); mBaiduMap.animateMapStatus(MapStatusUpdateFactory .newMapStatus(mapStatus)); isFirstLocation = false; } //让“我”显示在地图上 MyLocationData.Builder locationBuilder = new MyLocationData.Builder(); locationBuilder.latitude(location.getLatitude()); locationBuilder.longitude(location.getLongitude()); MyLocationData locationData = locationBuilder.build(); mBaiduMap.setMyLocationData(locationData); }

这里首先将位置信息封装到LatLng对象中,然后调用MapStatusUpdateFactory的newMapStatus()将LatLng对象传入,接着返回的MapStatusUpdate对象作为参数传入到BaiduMap的animateMapStatus()方法中。上述代码中还使用了一个变量来防止多次调用animateMapStatus()方法,因为移动地图只需要在程序第一次定位时调用一次。

同时为了显示一个当前设备的光标,可以利用MyLocationData.Builder类来实现,如代码所示,就可将“我”显示在地图上了。

二、滑动地图获取poi(逆地理编码)

1. 逆地理编码

前面已经提到了,我们这里滑动地图需要用到逆地理编码,也就是反向地理解析,逆地理编码就是将坐标转换为详细的地址信息,代码如下:

 //反向地理解析(含有poi列表) mGeoCoder.reverseGeoCode(new ReverseGeoCodeOption().location(center)); /** * 反向地理解析,结果中含有poi信息,用于刚进入地图和移动地图时使用 */ private void initGeoCoder() { mGeoCoder = GeoCoder.newInstance(); mGeoCoder.setOnGetGeoCodeResultListener(new OnGetGeoCoderResultListener() { @Override public void onGetGeoCodeResult(GeoCodeResult geoCodeResult) { } @Override public void onGetReverseGeoCodeResult(ReverseGeoCodeResult reverseGeoCodeResult) { if (reverseGeoCodeResult.error.equals(SearchResult.ERRORNO.NO_ERROR)) { //获取poi列表 if (reverseGeoCodeResult.getPoiList() != null) { poiInfoListForGeoCoder = reverseGeoCodeResult.getPoiList(); } } else { Toast.makeText(mContext, "该位置范围内无信息
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值