我是靠谱客的博主 多情豌豆,最近开发中收集的这篇文章主要介绍Android高德地图 实现定位 周边热点 POI搜索 BottomSheetBehavior 动态获取权限demo,觉得挺不错的,现在分享给大家,希望可以做个参考。
概述
首先我们先看下效果 demo中包含了两种不同风格的地图定位效果展示,一种仿IOS的苹果地图实现的界面 地图抽屉栏展示 通过手势滑动可以实现底部栏的BottomSheetBehavior 可以通过上下拖拽 隐藏或者全屏效果
项目地址:https://github.com/xinjilong/GaodeIosStyle2
第二种效果也是 常见的开发的需求 屏幕一分为2 一半为地图展示一半为热点地址显示 滑动地图地址更新效果
针对高德地图的引用 首先我们需要到高德官方 进行key 的申请,( JAR的引用 SO文件的加载 项目中已经有可以直接复制)
清单文件的配置key 以及定位需要的service
<!--高德地图需要的key,根据官方API将自己申请的key进行替换 value--> <meta-data android:name="com.amap.api.v2.apikey" android:value="9d8d5b93db86edce55ccb4432fb0f464"/> <!--定位需要服务--> <service android:name="com.amap.api.location.APSService"></service>
添加权限
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.xinyang.alienware.gaodeiosstyle"> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.READ_PHONE_STATE" /> <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.CHANGE_CONFIGURATION" /> <uses-permission android:name="android.permission.WAKE_LOCK" /> <uses-permission android:name="android.permission.WRITE_SETTINGS" /> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme"> <!--高德地图需要的key,根据官方API将自己申请的key进行替换 value--> <meta-data android:name="com.amap.api.v2.apikey" android:value="9d8d5b93db86edce55ccb4432fb0f464"/> <!--定位需要服务--> <service android:name="com.amap.api.location.APSService"></service> <!--android:windowSoftInputMode="adjustPan" 注意此属性防止软键盘将底部顶上去>--> <activity android:name=".MainActivity" android:screenOrientation="portrait" android:windowSoftInputMode="adjustPan"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <!--动态获取权限--> <activity android:name=".permissions.PermissionsActivity" android:screenOrientation="portrait" android:windowSoftInputMode="adjustResize"/> </application>
定位需要的相关操作
mapView.onCreate(savedInstanceState); //此方法必须写否则加载空白 if (aMap == null) { aMap = mapView.getMap(); } aMap.moveCamera(CameraUpdateFactory.zoomTo(18));//缩放等级 initLocation();
/*** * 初始化定位 */ private void initLocation() { if (aMap != null){ MyLocationStyle locationStyle = new MyLocationStyle(); // locationStyle.myLocationIcon(BitmapDescriptorFactory.fromResource(R.drawable.em_unread_count_bg)); locationStyle.strokeColor(Color.BLACK); locationStyle.radiusFillColor(Color.argb(100,0,0,180)); locationStyle.strokeWidth(1.0f); aMap.setMyLocationStyle( locationStyle); aMap.setLocationSource(this); aMap.getUiSettings().setMyLocationButtonEnabled(true); aMap.setMyLocationEnabled(true); //监听地图发生变化之后 aMap.setOnCameraChangeListener(new AMap.OnCameraChangeListener() { @Override public void onCameraChange(CameraPosition cameraPosition) { //发生变化时获取到经纬度传递逆地理编码获取周边数据 regeocodeSearch(cameraPosition.target.latitude,cameraPosition.target.longitude,2000); point = new LatLng(cameraPosition.target.latitude,cameraPosition.target.longitude); marker.remove();//将上一次描绘的mark清除 } @Override public void onCameraChangeFinish(CameraPosition cameraPosition) { //地图发生变化之后描绘mark marker = aMap.addMarker(new com.amap.api.maps.model.MarkerOptions() .position(point) .title("") .icon(BitmapDescriptorFactory.fromResource(R.drawable.em_unread_count_bg))); } }); } }
/** * 方法必须重写 */ @Override public void onResume() { super.onResume(); mapView.onResume(); } /** * 方法必须重写 */ @Override public void onPause() { super.onPause(); mapView.onPause(); } /** * 方法必须重写 */ @Override public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); mapView.onSaveInstanceState(outState); } /** * 方法必须重写 */ @Override public void onDestroy() { super.onDestroy(); mapView.onDestroy(); } @Override public void activate(OnLocationChangedListener onLocationChangedListener) { mListener = onLocationChangedListener; if (mlocationClient == null){ mlocationClient = new AMapLocationClient(getActivity().getApplicationContext()); mLocationOption = new AMapLocationClientOption(); mlocationClient.setLocationListener(this); mLocationOption.setOnceLocation(true); //只定位一次 mLocationOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy); mlocationClient.setLocationOption(mLocationOption); mlocationClient.startLocation(); } } @Override public void deactivate() { mListener = null; if (mlocationClient !=null){ mlocationClient.stopLocation(); mlocationClient.onDestroy(); } mlocationClient = null; mLocationOption = null; }
对着地图滑动变化进行热点数据更新
@Override public void onLocationChanged(AMapLocation aMapLocation) { if (aMapLocation!=null && mListener != null){ if (aMapLocation != null && aMapLocation.getErrorCode() == 0){ mListener.onLocationChanged(aMapLocation); Double weidu = aMapLocation.getLatitude(); Double jingdu = aMapLocation.getLongitude(); regeocodeSearch(weidu, jingdu, 2000); }else { String errorText = "faild to located"+aMapLocation.getErrorCode()+":"+aMapLocation.getErrorInfo(); Log.d("ceshi",errorText); } } }
逆向地理编码获取到搜索热点地址
/*** * 逆地理编码获取定位后的附近地址 * @param weidu * @param jingdu * @param distances 设置查找范围 */ private void regeocodeSearch(Double weidu, Double jingdu, int distances ) { LatLonPoint point = new LatLonPoint(weidu,jingdu); GeocodeSearch geocodeSearch = new GeocodeSearch(getActivity()); RegeocodeQuery regeocodeQuery = new RegeocodeQuery(point,distances,geocodeSearch.AMAP); geocodeSearch.getFromLocationAsyn(regeocodeQuery); geocodeSearch.setOnGeocodeSearchListener(new GeocodeSearch.OnGeocodeSearchListener() { @Override public void onRegeocodeSearched(RegeocodeResult regeocodeResult, int rCode) { String preAdd = "";//地址前缀 if (1000 == rCode) { final RegeocodeAddress address = regeocodeResult.getRegeocodeAddress(); StringBuffer stringBuffer = new StringBuffer(); String area = address.getProvince();//省或直辖市 String loc = address.getCity();//地级市或直辖市 String subLoc = address.getDistrict();//区或县或县级市 String ts = address.getTownship();//乡镇 String thf = null;//道路 List<RegeocodeRoad> regeocodeRoads = address.getRoads();//道路列表 if (regeocodeRoads != null && regeocodeRoads.size() > 0) { RegeocodeRoad regeocodeRoad = regeocodeRoads.get(0); if (regeocodeRoad != null) { thf = regeocodeRoad.getName(); } } String subthf = null;//门牌号 StreetNumber streetNumber = address.getStreetNumber(); if (streetNumber != null) { subthf = streetNumber.getNumber(); } String fn = address.getBuilding();//标志性建筑,当道路为null时显示 if (area != null) { stringBuffer.append(area); preAdd += area; } if (loc != null && !area.equals(loc)) { stringBuffer.append(loc); preAdd += loc; } if (subLoc != null) { stringBuffer.append(subLoc); preAdd += subLoc; } if (ts != null) stringBuffer.append(ts); if (thf != null) stringBuffer.append(thf); if (subthf != null) stringBuffer.append(subthf); if ((thf == null && subthf == null) && fn != null && !subLoc.equals(fn)) stringBuffer.append(fn + "附近"); // String ps = "poi"; pois = address.getPois();//获取周围兴趣点 adapter = new ChoutiRecyclerViewAdapter(getActivity(),pois); recyclerView.setAdapter(adapter); recyclerView.setItemAnimator(new DefaultItemAnimator()); adapter.setItemClickListener(new ChoutiRecyclerViewAdapter.ItemClickListener() { @Override public void onItemClick(View view, int pos) { Toast.makeText(getActivity(), "postion:"+pos+"地址:" +pois.get(pos).getTitle(), Toast.LENGTH_LONG).show(); } }); } } @Override public void onGeocodeSearched(GeocodeResult geocodeResult, int i) { } }); }
POI 搜索
@Override public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) { keyWord = String.valueOf(charSequence); mHint.setText("搜索结果"); mHint.setTextColor(getResources().getColor(R.color.bbb_color)); if ("".equals(keyWord)) { // Toast.makeText(getActivity(),"请输入搜索关键字",Toast.LENGTH_SHORT).show(); return; } else { doSearchQuery(); } } @Override public void afterTextChanged(Editable editable) { } });
/*** * POI搜索变 * @param */ private void doSearchQuery() { currentPage = 0; //不输入城市名称有些地方搜索不到 query = new PoiSearch.Query(keyWord, "", "北京");// 第一个参数表示搜索字符串,第二个参数表示poi搜索类型,第三个参数表示poi搜索区域(空字符串代表全国) //这里没有做分页加载了,默认给50条数据 query.setPageSize(50);// 设置每页最多返回多少条poiitem query.setPageNum(currentPage);// 设置查第一页 poiSearch = new PoiSearch(getActivity(), query); poiSearch.setOnPoiSearchListener(this); poiSearch.searchPOIAsyn(); } /** * POI信息查询回调方法 */ @Override public void onPoiSearched(PoiResult result, int rCode) { if (rCode == AMapException.CODE_AMAP_SUCCESS) { if (result != null && result.getQuery() != null) { // 搜索poi的结果 if (result.getQuery().equals(query)) { // 是否是同一条 poiResult = result; final ArrayList<PoiAddressBean> data = new ArrayList<PoiAddressBean>();//自己创建的数据集合 // 取得搜索到的poiitems有多少页 List<PoiItem> poiItems = poiResult.getPois();// 取得第一页的poiitem数据,页数从数字0开始 List<SuggestionCity> suggestionCities = poiResult .getSearchSuggestionCitys();// 当搜索不到poiitem数据时,会返回含有搜索关键字的城市信息 for(PoiItem item : poiItems){ //获取经纬度对象 LatLonPoint llp = item.getLatLonPoint(); double lon = llp.getLongitude(); double lat = llp.getLatitude(); String title = item.getTitle(); String text = item.getSnippet(); String provinceName = item.getProvinceName(); String cityName = item.getCityName(); String adName = item.getAdName(); data.add(new PoiAddressBean(String.valueOf(lon), String.valueOf(lat), title, text,provinceName, cityName,adName)); } PoiKeywordSearchAdapter poiadapter = new PoiKeywordSearchAdapter(getActivity(),data); recyclerView.setAdapter(poiadapter); poiadapter.setItemClickListener(new PoiKeywordSearchAdapter.PoiItemClickListener() { @Override public void onItemClick(View view, int pos) { Double poiLatitude = Double.valueOf(data.get(pos).getLatitude()).doubleValue(); Double poiLongtude = Double.valueOf(data.get(pos).getLongitude()).doubleValue(); //通过经纬度重新再地图获取位置 CameraPosition cp = aMap.getCameraPosition(); CameraPosition cpNew = CameraPosition.fromLatLngZoom(new LatLng(poiLatitude,poiLongtude),cp.zoom); CameraUpdate cu = CameraUpdateFactory.newCameraPosition(cpNew); aMap.moveCamera(cu); behavior.setState(4); //设置底部bottom sheet为半隐藏 searchead.setText(null);//清空Edittext内容 mHint.setText("附近热点"); mHint.setTextColor(getResources().getColor(R.color.tab_Indicator_color)); Log.d("ceshi","postion"+pos+"lat"+data.get(pos).getLatitude()+"long:"+data.get(pos).getLongitude()); } }); } } else { Toast.makeText(getActivity(),"no_result",Toast.LENGTH_SHORT).show(); } } else { Toast.makeText(getActivity(),""+rCode,Toast.LENGTH_SHORT).show(); } } /** * POI信息查询回调方法 */ @Override public void onPoiItemSearched(PoiItem poiItem, int i) { }
BottomSheetBehavior 控制
bottomSheet = parentView.findViewById(R.id.bottom_sheet); behavior = BottomSheetBehavior.from(bottomSheet);behavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() { @Override public void onStateChanged(@NonNull View bottomSheet, @BottomSheetBehavior.State int newState) { String state = "null"; switch (newState) { case 1: state = "STATE_DRAGGING";//过渡状态此时用户正在向上或者向下拖动bottom sheet KeyBoardUtils.closeKeyBoard(searchead,getActivity()); break; case 2: state = "STATE_SETTLING"; // 视图从脱离手指自由滑动到最终停下的这一小段时间 break; case 3: state = "STATE_EXPANDED"; //处于完全展开的状态 break; case 4: state = "STATE_COLLAPSED"; //默认的折叠状态 KeyBoardUtils.closeKeyBoard(searchead,getActivity()); break; case 5: state = "STATE_HIDDEN"; //下滑动完全隐藏 bottom sheet KeyBoardUtils.closeKeyBoard(searchead,getActivity()); break; } } @Override public void onSlide(@NonNull View bottomSheet, float slideOffset) { // Log.d("BottomSheetDemo", "slideOffset:" + slideOffset); } });
最后
以上就是多情豌豆为你收集整理的Android高德地图 实现定位 周边热点 POI搜索 BottomSheetBehavior 动态获取权限demo的全部内容,希望文章能够帮你解决Android高德地图 实现定位 周边热点 POI搜索 BottomSheetBehavior 动态获取权限demo所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复