不得不说,我很少写博客,但是这次公司需要将百度地图转换为高德开发,大概需求是:支持自动定位,支持覆盖物,支持数据同步,支持PIO检索。很纳闷得是,好不容易完成后,项目碎片切换出现,地图服务初始化,原定位后面功能全部销毁了。很是纳闷,综合了网上的一些言论,大概就是一些使命在fragment生命周期做文章的列子。不多说啥,代码贴上。
1.初始化方面的判断
if (aMap == null) {
aMap = mapView.getMap(); setUpMap();}
然而,这样在activity中确实不会出现什么问题,但是在fragment中,出现Ondestory不走的情况,直接走OndestoryView 的情况。直接导致碎片切换回来,出现个北京地图.
反复log打印检测,init()方法里面的这个初始化判断出错,定位从新刷新
if (aMap == null) { aMap = mapView.getMap(); setUpMap(); }else{ aMap.clear(); aMap.setLocationSource(this); // amap.getUiSettings().setMyLocationButtonEnabled(false); // amap.getUiSettings().setZoomControlsEnabled(false); aMap.setMyLocationEnabled(true); aMap = mapView.getMap(); setUpMap(); }上面进行了判断之后,问题是解决了,但是又有一个新问题,就是高德地图客服所说的,Ondertoryview的问题
具体代码如下:
@Override public void onDestroy() { super.onDestroy(); L.e("MY"+"--------------------------Destory-------------------------"); mapView.onDestroy(); } @Override public void onResume() { super.onResume(); Log.e("MY","-------------------------------Resume-----------------------"); mapView.onResume(); } /*用户离开fragment是停止定位*/ @Override public void onPause() { super.onPause(); mapView.onPause(); deactivate(); Log.e("PCF","------------------Pause----------------"); }
/* 以下是高德搞事情*/ /** * 定位成功后回调函数 */ @Override public void onLocationChanged(AMapLocation amapLocation) { Log.i("MY", "onLocationChanged"+"11111111111111111111"); if (mListener != null && amapLocation != null) { if (amapLocation != null && amapLocation.getErrorCode() == 0) { mListener.onLocationChanged(amapLocation); LatLng curLatlng = new LatLng(amapLocation.getLatitude(), amapLocation.getLongitude()); searchLatlonPoint = new LatLonPoint(curLatlng.latitude, curLatlng.longitude); aMap.moveCamera(CameraUpdateFactory.newLatLngZoom(curLatlng, 16f)); isInputKeySearch = false; searchText.setText(""); } else { String errText = "定位失败," + amapLocation.getErrorCode() + ": " + amapLocation.getErrorInfo(); Log.e("AmapErr", errText); } } } /** * 激活定位 */ @Override public void activate(OnLocationChangedListener listener) { Log.e("MY","-----------------激活定位------------------------------"); mListener = listener; if (mlocationClient == null) { mlocationClient = new AMapLocationClient(context); mLocationOption = new AMapLocationClientOption(); //设置定位监听 mlocationClient.setLocationListener(this); //设置为高精度定位模式 mLocationOption.setOnceLocation(true); mLocationOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy); //设置定位参数 mlocationClient.setLocationOption(mLocationOption); // 此方法为每隔固定时间会发起一次定位请求,为了减少电量消耗或网络流量消耗, // 注意设置合适的定位时间的间隔(最小间隔支持为2000ms),并且在合适时间调用stopLocation()方法来取消定位请求 // 在定位结束后,在合适的生命周期调用onDestroy()方法 // 在单次定位情况下,定位无论成功与否,都无需调用stopLocation()方法移除请求,定位sdk内部会移除 mlocationClient.startLocation(); } } /** * 停止定位 */ @Override public void deactivate() { Log.e("MY","-----------------停止定位----------------"); mListener = null; if (mlocationClient != null) { mlocationClient.stopLocation(); mlocationClient.onDestroy(); } mlocationClient = null; } /** * 响应逆地理编码 */ public void geoAddress() { // Log.i("MY", "geoAddress"+ searchLatlonPoint.toString()); showDialog(); searchText.setText(""); if (searchLatlonPoint != null) { RegeocodeQuery query = new RegeocodeQuery(searchLatlonPoint, 200, GeocodeSearch.AMAP);// 第一个参数表示一个Latlng,第二参数表示范围多少米,第三个参数表示是火系坐标系还是GPS原生坐标系 geocoderSearch.getFromLocationAsyn(query); } } /** * 开始进行poi搜索 */ /** * 开始进行poi搜索 */ protected void doSearchQuery() { // Log.i("MY", "doSearchQuery"); currentPage = 0; query = new PoiSearch.Query(searchKey, searchType, "");// 第一个参数表示搜索字符串,第二个参数表示poi搜索类型,第三个参数表示poi搜索区域(空字符串代表全国) query.setCityLimit(true); query.setPageSize(20); query.setPageNum(currentPage); if (searchLatlonPoint != null) { poiSearch = new PoiSearch(context, query); poiSearch.setOnPoiSearchListener(this); poiSearch.setBound(new PoiSearch.SearchBound(searchLatlonPoint, 1000, true));// poiSearch.searchPOIAsyn(); } } @Override public void onRegeocodeSearched(RegeocodeResult result, int rCode) { dismissDialog(); if (rCode == AMapException.CODE_AMAP_SUCCESS) { if (result != null && result.getRegeocodeAddress() != null && result.getRegeocodeAddress().getFormatAddress() != null) { String address = result.getRegeocodeAddress().getProvince() + result.getRegeocodeAddress().getCity() + result.getRegeocodeAddress().getDistrict() + result.getRegeocodeAddress().getTownship(); firstItem = new PoiItem("regeo", searchLatlonPoint, address, address); doSearchQuery(); } } else { Toast.makeText(context, "error code is " + rCode, Toast.LENGTH_SHORT).show(); } } @Override public void onGeocodeSearched(GeocodeResult geocodeResult, int i) { } /** * POI搜索结果回调 * * @param poiResult 搜索结果 * @param resultCode 错误码 */ @Override public void onPoiSearched(PoiResult poiResult, int resultCode) { if (resultCode == AMapException.CODE_AMAP_SUCCESS) { if (poiResult != null && poiResult.getQuery() != null) { if (poiResult.getQuery().equals(query)) { poiItems = poiResult.getPois(); if (poiItems != null && poiItems.size() > 0) { updateListview(poiItems); } else { Toast.makeText(getActivity(), "无搜索结果", Toast.LENGTH_SHORT).show(); } } } else { Toast.makeText(getActivity(), "无搜索结果", Toast.LENGTH_SHORT).show(); } } } @Override public void onPoiItemSearched(PoiItem poiItem, int i) { } /** * 更新列表中的item * * @param poiItems */ private void updateListview(ListpoiItems) { resultData.clear(); searchResultAdapter.setSelectedPosition(0); resultData.add(firstItem); resultData.addAll(poiItems); searchResultAdapter.setData(resultData); searchResultAdapter.notifyDataSetChanged(); } AdapterView.OnItemClickListener onItemClickListener = new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView> parent, View view, int position, long id) { if (position != searchResultAdapter.getSelectedPosition()) { PoiItem poiItem = (PoiItem) searchResultAdapter.getItem(position); LatLng curLatlng = new LatLng(poiItem.getLatLonPoint().getLatitude(), poiItem.getLatLonPoint().getLongitude()); isItemClickAction = true; aMap.moveCamera(CameraUpdateFactory.newLatLngZoom(curLatlng, 16f)); searchResultAdapter.setSelectedPosition(position); searchResultAdapter.notifyDataSetChanged(); } } }; /*显示showDialog*/ public void showDialog() { progDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER); progDialog.setIndeterminate(false); progDialog.setCancelable(true); progDialog.setMessage("正在加载..."); progDialog.show(); } /* 影藏*/ public void dismissDialog() { if (progDialog != null) { progDialog.dismiss(); } } private void addMarkerInScreenCenter(LatLng locationLatLng) { LatLng latLng = aMap.getCameraPosition().target; Point screenPosition = aMap.getProjection().toScreenLocation(latLng); locationMarker = aMap.addMarker(new MarkerOptions() .anchor(0.5f, 0.5f) .icon(BitmapDescriptorFactory.fromResource(R.drawable.purple_pin))); //设置Marker在屏幕上,不跟随地图移动 locationMarker.setPositionByPixels(screenPosition.x, screenPosition.y); locationMarker.setZIndex(1); } /** * 屏幕中心marker 跳动 中心点的移动 */ public void startJumpAnimation() { if (locationMarker != null) { //根据屏幕距离计算需要移动的目标点 final LatLng latLng = locationMarker.getPosition(); Point point = aMap.getProjection().toScreenLocation(latLng); point.y -= dip2px(getActivity(), 125); LatLng target = aMap.getProjection() .fromScreenLocation(point); //使用TranslateAnimation,填写一个需要移动的目标点 Animation animation = new TranslateAnimation(target); animation.setInterpolator(new Interpolator() { @Override public float getInterpolation(float input) { // 模拟重加速度的interpolator if (input <= 0.5) { return (float) (0.5f - 2 * (0.5 - input) * (0.5 - input)); } else { return (float) (0.5f - Math.sqrt((input - 0.5f) * (1.5f - input))); } } }); //整个移动所需要的时间 animation.setDuration(600); //设置动画 locationMarker.setAnimation(animation); //开始动画 locationMarker.startAnimation(); } else { Log.e("amaFF", "screenMarker is null"); } } //dip和px转换 private static int dip2px(Context context, float dpValue) { final float scale = context.getResources().getDisplayMetrics().density; return (int) (dpValue * scale + 0.5f); } Inputtips.InputtipsListener inputtipsListener = new Inputtips.InputtipsListener() { @Override public void onGetInputtips(List list, int rCode) { if (rCode == AMapException.CODE_AMAP_SUCCESS) {// 正确返回 autoTips = list; List listString = new ArrayList (); for (int i = 0; i < list.size(); i++) { listString.add(list.get(i).getName()); } ArrayAdapter aAdapter = new ArrayAdapter ( context, R.layout.route_inpits, listString); searchText.setAdapter(aAdapter); aAdapter.notifyDataSetChanged(); if (isfirstinput) { isfirstinput = false; searchText.showDropDown(); } } else { Toast.makeText(context, "erroCode " + rCode, Toast.LENGTH_SHORT).show(); } } }; private boolean isInputKeySearch; private String inputSearchKey; private void searchPoi(Tip result) { isInputKeySearch = true; inputSearchKey = result.getName();//getAddress(); // + result.getRegeocodeAddress().getCity() + result.getRegeocodeAddress().getDistrict() + result.getRegeocodeAddress().getTownship(); searchLatlonPoint = result.getPoint(); firstItem = new PoiItem("tip", searchLatlonPoint, inputSearchKey, result.getAddress()); firstItem.setCityName(result.getDistrict()); firstItem.setAdName(""); resultData.clear(); searchResultAdapter.setSelectedPosition(0); aMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(searchLatlonPoint.getLatitude(), searchLatlonPoint.getLongitude()), 16f)); hideSoftKey(searchText); doSearchQuery(); } private void hideSoftKey(View view) { InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE); imm.showSoftInput(view, InputMethodManager.SHOW_FORCED); imm.hideSoftInputFromWindow(view.getWindowToken(), 0); }
为了方便同行好copy,我干脆直接来代码,没搞图。map初始化actiivity是oncreate()方法里,map.oncreate(),fragment里面,2个方法类体,oncreateview(),onviewcreate(),其实很多可以自动2次封装,搞个baseactivity 或者 baseFragment ,统一管理方法主体。好了,不多说了。
详细代码下载请看我下一篇文章
具体高德搞什么事情,请看下篇文章