轉(zhuǎn)載請(qǐng)注明!
前言
使用高德SDK實(shí)現(xiàn)定位及周邊的搜索界面,先看效果圖:
使用到了高德以下sdk:
com.amap.api:3dmap:latest.integration
com.amap.api:search:latest.integration
思路分析
本文不對(duì)高德sdk的集成做介紹,主要說(shuō)說(shuō)實(shí)現(xiàn)該頁(yè)面的思路。
需求:
- 進(jìn)入頁(yè)面自動(dòng)定位,并且展示周邊
- 搜索地點(diǎn),并且展示該地點(diǎn)周邊
- 周邊列表的點(diǎn)擊,然后切換地圖的定位藍(lán)點(diǎn)
具體實(shí)現(xiàn)
首先需要注意權(quán)限的獲取。
初始化高德相關(guān)的東西:
/**
* 初始化定位相關(guān)
*/
private fun initLocationAbout() {
val myLocationStyle = MyLocationStyle()
myLocationStyle.showMyLocation(true)
myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_SHOW)
//設(shè)置默認(rèn)定位按鈕是否顯示
mMap.uiSettings.isMyLocationButtonEnabled = false
//設(shè)置為true表示啟動(dòng)顯示定位藍(lán)點(diǎn),false表示隱藏定位藍(lán)點(diǎn)并不進(jìn)行定位,默認(rèn)是false
mMap.isMyLocationEnabled = true
mMap.myLocationStyle = myLocationStyle
//第一次定位
mMap.setOnMyLocationChangeListener {
val latLng = LatLng(it.latitude, it.longitude)
cameraMove(latLng)
}
mMap.setOnCameraChangeListener(object : AMap.OnCameraChangeListener {
override fun onCameraChangeFinish(p0: CameraPosition) {
cameraMarkers(p0.target)
//判斷是否需要搜索周邊
if (isSearchRound) {
poiSearch(p0.target)
}
isSearchRound = true
}
override fun onCameraChange(p0: CameraPosition) {
}
})
}
移動(dòng)定位點(diǎn)的方法:
/**
* 移動(dòng)地圖
* @param latLng 坐標(biāo)
*/
private fun cameraMove(latLng: LatLng) {
//其中的18f表示的是地圖放大級(jí)別
val camera = CameraUpdateFactory.newCameraPosition(CameraPosition(latLng, 18f, 0f, 0f))
mMap.moveCamera(camera)
}
周邊搜索的方法:
/**
* 周邊搜索
*/
private fun poiSearch(latLng: LatLng) {
val point = LatLonPoint(latLng.latitude, latLng.longitude)
val geocodeSearch = GeocodeSearch(this)
val regeocodeQuery = RegeocodeQuery(point, 200f, GeocodeSearch.AMAP)
geocodeSearch.getFromLocationAsyn(regeocodeQuery)
geocodeSearch.setOnGeocodeSearchListener(object : GeocodeSearch.OnGeocodeSearchListener {
/**
* 逆地理編碼
*/
override fun onRegeocodeSearched(p0: RegeocodeResult, p1: Int) {
if (p1 == AMapException.CODE_AMAP_SUCCESS) {
//創(chuàng)建當(dāng)前位置的poi
val nowPoiltem = PoiItem(
"111",
p0.regeocodeQuery.point,
"地圖位置",
p0.regeocodeAddress.formatAddress
)
nowPoiltem.adCode = p0.regeocodeAddress.adCode
nowPoiltem.provinceName = p0.regeocodeAddress.province
nowPoiltem.cityName = p0.regeocodeAddress.city
nowPoiltem.adName = p0.regeocodeAddress.district
val locationList = mutableListOf<PoiItem>()
//因?yàn)樗阉鞯闹苓吜斜聿⒉话?dāng)前搜索的位置,所以需要把當(dāng)前位置插進(jìn)去
locationList.add(nowPoiltem)
locationList.addAll(p0.regeocodeAddress.pois)
//周邊展示的Adapter
mAdapter.setCityAbout(
p0.regeocodeAddress.province,
p0.regeocodeAddress.city,
p0.regeocodeAddress.district
)
mAdapter.replaceData(locationList)
mAdapter.setEmptyView(mNoData)
} else {
mAdapter.setEmptyView(mErrorLoad)
}
}
/**
* 地理編碼
*/
override fun onGeocodeSearched(p0: GeocodeResult?, p1: Int) {
hideLoading()
}
})
}
關(guān)鍵字搜索:
/**
* 搜索關(guān)鍵字
*/
private fun doSearchQuery(keyWord: String) {
val query = PoiSearch.Query(keyWord, "", mCity)
query.pageSize = 50
query.pageNum = 0
//搜索
val poiSearch = PoiSearch(this, query)
poiSearch.setOnPoiSearchListener(this)
poiSearch.searchPOIAsyn()
showLoading()
}
/**
* 可以在回調(diào)中解析result,獲取POI信息
* result.getPois()可以獲取到PoiItem列表,Poi詳細(xì)信息可參考PoiItem類
* 返回結(jié)果成功或者失敗的響應(yīng)碼。1000為成功,其他為失?。ㄔ敿?xì)信息參見網(wǎng)站開發(fā)指南-實(shí)用工具-錯(cuò)誤碼對(duì)照表)
*/
override fun onPoiSearched(p0: PoiResult, p1: Int) {
hideLoading()
if (p1 == AMapException.CODE_AMAP_SUCCESS) {
mPopupLocation.replaceData(p0.pois)
//彈出框
mXPopup?.show()
} else {
App.mApplication.toast("搜索地址錯(cuò)誤!")
}
}
周邊列表的點(diǎn)擊:
mAdapter.setOnItemClickListener { adapter, view, position ->
val data: PoiItem = adapter.data[position] as PoiItem
isSearchRound = false
mSelectLocation = position
mAdapter.selectLocation(position)
//移動(dòng)點(diǎn)
val latLng = LatLng(data.latLonPoint.latitude, data.latLonPoint.longitude)
//創(chuàng)建
cameraMove(latLng)
}
頁(yè)面功能通過(guò)以上方法就能實(shí)現(xiàn),如果發(fā)現(xiàn)某些監(jiān)聽不會(huì)回調(diào),先看看引入的sdk。在編寫時(shí),我一開始引用的高德的2dmap,發(fā)現(xiàn)地圖移動(dòng)的監(jiān)聽不會(huì)回調(diào),然后換到3dmap就好了。