Android百度地圖實(shí)現(xiàn)搜索和定位及自定義圖標(biāo)繪制并點(diǎn)擊時(shí)彈出泡泡
一、問(wèn)題描述
上一次我們使用百度地圖實(shí)現(xiàn)基本的定位功能,接下來(lái)我們繼續(xù)實(shí)現(xiàn)搜索和定位,并使用LocationOverlay繪制定位位置,同時(shí)展示如何使用自定義圖標(biāo)繪制并點(diǎn)擊時(shí)彈出泡泡
如圖所示:
二、編寫(xiě)MyApplication類(lèi)
public class MyApplication extends Application { private static MyApplication mInstance = null; public boolean m_bKeyRight = true; public BMapManager mBMapManager = null; public static final String strKey = "申請(qǐng)的應(yīng)用key"; @Override public void onCreate() { super.onCreate(); mInstance = this; initEngineManager(this); } public void initEngineManager(Context context) { if (mBMapManager == null) { mBMapManager = new BMapManager(context); } if (!mBMapManager.init(strKey,new MyGeneralListener())) { Toast.makeText(MyApplication.getInstance().getApplicationContext(), "BMapManager 初始化錯(cuò)誤!", Toast.LENGTH_LONG).show(); } } public static MyApplication getInstance() { return mInstance; } // 常用事件監(jiān)聽(tīng),用來(lái)處理通常的網(wǎng)絡(luò)錯(cuò)誤,授權(quán)驗(yàn)證錯(cuò)誤等 public static class MyGeneralListener implements MKGeneralListener { @Override public void onGetNetworkState(int iError) { if (iError == MKEvent.ERROR_NETWORK_CONNECT) { Toast.makeText(MyApplication.getInstance().getApplicationContext(), "您的網(wǎng)絡(luò)出錯(cuò)啦!",Toast.LENGTH_LONG).show(); }else if (iError == MKEvent.ERROR_NETWORK_DATA) { Toast.makeText(MyApplication.getInstance().getApplicationContext(), "輸入正確的檢索條件!",Toast.LENGTH_LONG).show(); } } @Override public void onGetPermissionState(int iError) { //非零值表示key驗(yàn)證未通過(guò) if (iError != 0) { //授權(quán)Key錯(cuò)誤: Toast.makeText(MyApplication.getInstance().getApplicationContext(), "請(qǐng)?jiān)?DemoApplication.java文件輸入正確的授權(quán)Key,并檢查您的網(wǎng)絡(luò)連接是否正常!error: "+iError, Toast.LENGTH_LONG).show(); MyApplication.getInstance().m_bKeyRight = true; } else{ MyApplication.getInstance().m_bKeyRight = true; //Toast.makeText(DemoApplication.getInstance().getApplicationContext(), "key認(rèn)證成功", Toast.LENGTH_LONG).show(); } } } }
三、編寫(xiě)MyLocationMapView,繼承MapView重寫(xiě)onTouchEvent實(shí)現(xiàn)泡泡處理操作
public class MyLocationMapView extends MapView { public static PopupOverlay pop = null;// 彈出泡泡圖層,點(diǎn)擊圖標(biāo)使用 public MyLocationMapView(Context context) { super(context); } public MyLocationMapView(Context context, AttributeSet attrs) { super(context, attrs); } public MyLocationMapView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } @Override public boolean onTouchEvent(MotionEvent event) { if (!super.onTouchEvent(event)) { // 消隱泡泡 if (pop != null && event.getAction() == MotionEvent.ACTION_UP) pop.hidePop(); } return true; } }
三、編寫(xiě)主程序MainActivity
編寫(xiě)主程序MainActivity,用來(lái)展示如何結(jié)合定位SDK實(shí)現(xiàn)定位,并使用MyLocation Overlay繪制定位位置 同時(shí)展示如何使用自定義圖標(biāo)繪制并點(diǎn)擊時(shí)彈出泡泡。
public class MainActivity extends Activity { private EditText txtAddr; // 定位相關(guān) LocationClient mLocClient; LocationData locData = null; public MyLocationListenner myListener = new MyLocationListenner(); public MyApplication app; //定位圖層 locationOverlay myLocationOverlay = null; //彈出泡泡圖層 private PopupOverlay pop = null;//彈出泡泡圖層,瀏覽節(jié)點(diǎn)時(shí)使用 private TextView popupText = null;//泡泡view private View viewCache = null; //地圖相關(guān),使用繼承MapView的MyLocationMapView目的是重寫(xiě)touch事件實(shí)現(xiàn)泡泡處理 //如果不處理touch事件,則無(wú)需繼承,直接使用MapView即可 public MyLocationMapView mMapView = null; // 地圖View private MapController mMapController = null; private MKSearch mMKSearch = null;//用于信息檢索服務(wù) //UI相關(guān) OnCheckedChangeListener radioButtonListener = null; TextView requestLocButton ,btSerach; boolean isRequest = false;//是否手動(dòng)觸發(fā)請(qǐng)求定位 boolean isFirstLoc = true;//是否首次定位 @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); /** * 使用地圖sdk前需先初始化BMapManager. * BMapManager是全局的,可為多個(gè)MapView共用,它需要地圖模塊創(chuàng)建前創(chuàng)建, * 并在地圖地圖模塊銷(xiāo)毀后銷(xiāo)毀,只要還有地圖模塊在使用,BMapManager就不應(yīng)該銷(xiāo)毀 */ app = (MyApplication)this.getApplication(); if (app.mBMapManager == null) { app.mBMapManager = new BMapManager(getApplicationContext()); /** * 如果BMapManager沒(méi)有初始化則初始化BMapManager */ app.mBMapManager.init(MyApplication.strKey,new MyApplication.MyGeneralListener()); } setContentView(R.layout.activity_main); txtAddr=(EditText)findViewById(R.id.txtAddr);//關(guān)鍵字輸入框 //監(jiān)聽(tīng)搜索單擊事件 btSerach= (TextView)findViewById(R.id.btOk); btSerach.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { mMKSearch.poiSearchInCity("", txtAddr.getText().toString()); } }); //定位按鈕 requestLocButton = (TextView)findViewById(R.id.btget); requestLocButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { requestLocClick(); } }); //地圖初始化 mMapView = (MyLocationMapView)findViewById(R.id.bmapView); mMapView.setTraffic(true);//設(shè)置地圖模式為交通視圖(也可為衛(wèi)星視圖) mMapController = mMapView.getController(); mMapView.getController().setZoom(15); mMapView.getController().enableClick(true); mMapView.setBuiltInZoomControls(true); //信息檢索初始化 mMKSearch = new MKSearch(); mMKSearch.init(app.mBMapManager, new MKSearchListener() { @Override public void onGetAddrResult(MKAddrInfo arg0, int arg1) { } @Override public void onGetBusDetailResult(MKBusLineResult arg0, int arg1) { } @Override public void onGetDrivingRouteResult(MKDrivingRouteResult arg0, int arg1) { } @Override public void onGetPoiDetailSearchResult(int arg0, int arg1) { } @Override public void onGetPoiResult(MKPoiResult res, int type, int error) { if (error == MKEvent.ERROR_RESULT_NOT_FOUND) { Toast.makeText(MainActivity.this, "抱歉,未找到結(jié)果", Toast.LENGTH_LONG).show(); return; } else if (error != 0 || res == null) { Toast.makeText(MainActivity.this, "搜索出錯(cuò)啦.."+error, Toast.LENGTH_LONG).show(); return; } PoiOverlay poiOverlay = new PoiOverlay(MainActivity.this, mMapView); poiOverlay.setData(res.getAllPoi()); mMapView.getOverlays().clear(); mMapView.getOverlays().add(poiOverlay); mMapView.refresh(); for (MKPoiInfo info : res.getAllPoi()) { if (info.pt != null) { mMapView.getController().animateTo(info.pt); break; } } } @Override public void onGetShareUrlResult(MKShareUrlResult arg0, int arg1, int arg2) { } @Override public void onGetSuggestionResult(MKSuggestionResult arg0, int arg1){ } @Override public void onGetTransitRouteResult(MKTransitRouteResult arg0, int arg1) { } @Override public void onGetWalkingRouteResult(MKWalkingRouteResult arg0, int arg1) { } }); createPaopao(); //定位初始化 mLocClient = new LocationClient( this ); locData = new LocationData(); mLocClient.registerLocationListener( myListener ); LocationClientOption option = new LocationClientOption(); option.setOpenGps(true);//打開(kāi)gps option.setAddrType("all");//返回的定位結(jié)果包含地址信息 option.disableCache(false);//禁止啟用緩存定位 option.setCoorType("bd09ll"); //設(shè)置坐標(biāo)類(lèi)型 option.setScanSpan(1000); mLocClient.setLocOption(option); mLocClient.start(); //定位圖層初始化 myLocationOverlay = new locationOverlay(mMapView); //設(shè)置定位數(shù)據(jù) myLocationOverlay.setData(locData); //添加定位圖層 mMapView.getOverlays().add(myLocationOverlay); myLocationOverlay.enableCompass(); //修改定位數(shù)據(jù)后刷新圖層生效 mMapView.refresh(); } /** * 手動(dòng)觸發(fā)一次定位請(qǐng)求 */ public void requestLocClick(){ isRequest = true; mLocClient.requestLocation(); Toast.makeText(MainActivity.this, "正在定位……", Toast.LENGTH_SHORT).show(); } /** * 創(chuàng)建彈出泡泡圖層 */ public void createPaopao(){ viewCache = getLayoutInflater().inflate(R.layout.custom_text_view, null); popupText =(TextView) viewCache.findViewById(R.id.textcache); //泡泡點(diǎn)擊響應(yīng)回調(diào) PopupClickListener popListener = new PopupClickListener(){ @Override public void onClickedPopup(int index) { } }; pop = new PopupOverlay(mMapView,popListener); MyLocationMapView.pop = pop; } /** * 定位SDK監(jiān)聽(tīng)函數(shù) */ public class MyLocationListenner implements BDLocationListener { @Override public void onReceiveLocation(BDLocation location) { if (location == null) return ; locData.latitude = location.getLatitude(); locData.longitude = location.getLongitude(); //如果不顯示定位精度圈,將accuracy賦值為0即可 locData.accuracy = location.getRadius(); // 此處可以設(shè)置 locData的方向信息, 如果定位 SDK 未返回方向信息,用戶可以自己實(shí)現(xiàn)羅盤(pán)功能添加方向信息。 locData.direction = location.getDerect(); //更新定位數(shù)據(jù) myLocationOverlay.setData(locData); //更新圖層數(shù)據(jù)執(zhí)行刷新后生效 mMapView.refresh(); //是手動(dòng)觸發(fā)請(qǐng)求或首次定位時(shí),移動(dòng)到定位點(diǎn) if (isRequest || isFirstLoc){ //移動(dòng)地圖到定位點(diǎn) //Log.d("LocationOverlay", "receive location, animate to it"); mMapController.animateTo(new GeoPoint((int)(locData.latitude* 1e6), (int)(locData.longitude * 1e6))); isRequest = false; myLocationOverlay.setLocationMode(LocationMode.FOLLOWING); } //首次定位完成 isFirstLoc = false; } public void onReceivePoi(BDLocation poiLocation) { if (poiLocation == null){ return ; } } } //繼承MyLocationOverlay重寫(xiě)dispatchTap實(shí)現(xiàn)點(diǎn)擊處理 public class locationOverlay extends MyLocationOverlay{ public locationOverlay(MapView mapView) { super(mapView); } @Override protected boolean dispatchTap() { //處理點(diǎn)擊事件,彈出泡泡 popupText.setBackgroundResource(R.drawable.popup); popupText.setText(mLocClient.getLastKnownLocation().getAddrStr()); pop.showPopup(BMapUtil.getBitmapFromView(popupText),new GeoPoint((int)(locData.latitude*1e6), (int)(locData.longitude*1e6)),8); return true; } } @Override protected void onPause() { mMapView.onPause(); if(app.mBMapManager!=null){ app.mBMapManager.stop(); } super.onPause(); } @Override protected void onResume() { mMapView.onResume(); if(app.mBMapManager!=null){ app.mBMapManager.start(); } super.onResume(); } @Override protected void onDestroy() { //退出時(shí)銷(xiāo)毀定位 if (mLocClient != null) mLocClient.stop(); mMapView.destroy(); if(app.mBMapManager!=null){ app.mBMapManager.destroy(); app.mBMapManager=null; } super.onDestroy(); } @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); mMapView.onSaveInstanceState(outState); } @Override protected void onRestoreInstanceState(Bundle savedInstanceState) { super.onRestoreInstanceState(savedInstanceState); mMapView.onRestoreInstanceState(savedInstanceState); } @Override public boolean onCreateOptionsMenu(Menu menu) { return true; } }
MainActivity的布局文件如下:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" > <FrameLayout android:layout_width="fill_parent" android:layout_height="fill_parent" > <com.jerehedu.ljb.MyLocationMapView android:id="@+id/bmapView" android:layout_width="fill_parent" android:layout_height="fill_parent" android:clickable="true" /> <RelativeLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_marginLeft="10dp" android:layout_marginRight="10dp" android:layout_marginTop="10dp" android:background="@drawable/edit_bg_all" > <EditText android:id="@+id/txtAddr" android:layout_width="fill_parent" android:layout_height="40dp" android:layout_centerVertical="true" android:layout_marginRight="2dp" android:layout_toLeftOf="@+id/btOk" android:background="@drawable/edit_bg_all" android:completionThreshold="2" android:drawableLeft="@drawable/qz_icon_seabar_search" android:hint="請(qǐng)輸入搜索關(guān)鍵字" /> <TextView android:id="@+id/btOk" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerVertical="true" android:layout_marginRight="2dp" android:layout_toLeftOf="@+id/s2" android:text="搜索" android:textSize="18sp" /> <ImageView android:id="@+id/s2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerVertical="true" android:layout_marginRight="2dp" android:layout_toLeftOf="@+id/btget" android:src="@drawable/slide_center" /> <TextView android:id="@+id/btget" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_centerVertical="true" android:text="定位" android:textSize="18sp" /> </RelativeLayout> </FrameLayout> </RelativeLayout>
通過(guò)以上內(nèi)容給大家分享了Android百度地圖實(shí)現(xiàn)搜索和定位及自定義圖標(biāo)繪制并點(diǎn)擊時(shí)彈出泡泡的相關(guān)知識(shí),希望對(duì)大家有所幫助。
- Android Studio搜索功能(查找功能)及快捷鍵圖文詳解
- Android實(shí)現(xiàn)搜索功能并本地保存搜索歷史記錄
- Android自定義View實(shí)現(xiàn)搜索框(SearchView)功能
- Android仿簡(jiǎn)書(shū)動(dòng)態(tài)searchview搜索欄效果
- Android搜索框SearchView屬性和用法詳解
- Android SearchView搜索框組件的使用方法
- Android遍歷所有文件夾和子目錄搜索文件
- Android搜索框組件SearchView的基本使用方法
- Android ListView用EditText實(shí)現(xiàn)搜索功能效果
- Android實(shí)現(xiàn)簡(jiǎn)單動(dòng)態(tài)搜索功能
相關(guān)文章
Android使用OKHttp包處理HTTP相關(guān)操作的基本用法講解
這篇文章主要介紹了Android使用OKHttp包處理HTTP相關(guān)操作的基本用法講解,包括操作如何利用OKHttp操作HTTP請(qǐng)求與處理緩存等內(nèi)容,需要的朋友可以參考下2016-07-07Android編程實(shí)現(xiàn)設(shè)置按鈕背景透明與半透明及圖片背景透明的方法
這篇文章主要介紹了Android編程實(shí)現(xiàn)設(shè)置按鈕背景透明與半透明及圖片背景透明的方法,結(jié)合實(shí)例形式較為詳細(xì)的分析了Button及ImageButton的背景屬性設(shè)置技巧,非常簡(jiǎn)單實(shí)用,需要的朋友可以參考下2015-12-12Android判斷App前臺(tái)運(yùn)行還是后臺(tái)運(yùn)行(運(yùn)行狀態(tài))
這篇文章主要介紹了Android判斷App前臺(tái)運(yùn)行還是后臺(tái)運(yùn)行的相關(guān)資料,需要的朋友可以參考下2016-04-04Android編程實(shí)現(xiàn)創(chuàng)建,刪除,判斷快捷方式的方法
這篇文章主要介紹了Android編程實(shí)現(xiàn)創(chuàng)建,刪除,判斷快捷方式的方法,結(jié)合實(shí)例形式分析了Android編程針對(duì)快捷方式的常用操作技巧,需要的朋友可以參考下2017-02-02Android彈窗ListPopupWindow的簡(jiǎn)單應(yīng)用詳解
這篇文章主要為大家詳細(xì)介紹了Android彈窗ListPopupWindow的簡(jiǎn)單應(yīng)用,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-11-11Android網(wǎng)絡(luò)狀態(tài)實(shí)時(shí)監(jiān)聽(tīng)實(shí)例代碼(二)
這篇文章主要介紹了Android網(wǎng)絡(luò)狀態(tài)實(shí)時(shí)監(jiān)聽(tīng)實(shí)例代碼(2)的相關(guān)資料,需要的朋友可以參考下2016-03-03Android系統(tǒng)view與SurfaceView的基本使用及區(qū)別分析
這篇文章主要為大家介紹了Android系統(tǒng)view與SurfaceView基本使用的案例分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步2022-03-03Android使用IntentService進(jìn)行apk更新示例代碼
這篇文章主要介紹了Android使用IntentService進(jìn)行apk更新示例代碼,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-01-01Android用StaticLayout實(shí)現(xiàn)文字轉(zhuǎn)化為圖片效果(類(lèi)似長(zhǎng)微博發(fā)送)
這篇文章主要給大家介紹了關(guān)于Android利用StaticLayout實(shí)現(xiàn)文字轉(zhuǎn)化為圖片效果,實(shí)現(xiàn)的效果類(lèi)似我們常見(jiàn)的長(zhǎng)微博效果,文中給出了詳細(xì)的示例代碼供大家參考學(xué)習(xí),需要的朋友們下面來(lái)一起看看吧。2017-08-08