大家都知道在高德地圖Android SDK中,InfoWindow是全局唯一的,並且這個infowindow與AMap和Marker有關,使用起來不是很靈活,並且沒法實現如下類似的需求:現在我們有一些自定義marker,或者查詢得到的poi數據,我們想在地圖上直觀的看到這些點具體情況(效果如下圖所示),而不是需要點擊每個marker,彈出一個infowindow來才能查看到它的消息。這種需求我們就需要考慮別的方式來實現了。
其實實現這個功能也很簡單,我們需要變通一下,從Marker去着手而非從InfoWindow去處理。我們知道將一個marker添加到地圖上時需要BitmapDescriptor對象,而BitmapDescriptor對象的獲取能是由BitmapDescriptorFactory來進行實例化的,實例化方法有如下幾個:
其中fromView這個方法就是我們實現這個功能的核心方法,從名字我們也可以推斷這個方法使我們可以通過一個具體的View來初始化一個Marker,這樣我們就可以去做這個功能了。
首先咱們先看下核心代碼:
//位置信息 double latitude = 39.908127; double longtitude = 116.375257; //顯示的內容 String tile = "一眼就知道我是誰了吧"; //初始化marker內容 MarkerOptions markerOptions = new MarkerOptions(); //這里很簡單就加了一個TextView,根據需求可以加載復雜的View TextView textView = new TextView(getApplicationContext()); textView.setText(tile); textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 15); textView.setTextColor(Color.BLACK); textView.setBackgroundResource(R.drawable.custom_info_bubble); //通過View獲取BitmapDescriptor對象 BitmapDescriptor markerIcon = BitmapDescriptorFactory .fromView(textView); markerOptions.position(new LatLng(latitude, longtitude)) .icon(markerIcon).title(tile).perspective(true); //添加到地圖上 aMap.addMarker(markerOptions);
基本代碼如上,我們來看下效果:
並且可以根據自己需要去變換樣式:
也可以這樣(大家根據自己需求去自定義實現自己想要個的功能)
最后來個例子吧,具體的應用場景為我查詢了周邊的團購信息,我想能直觀的看到都是哪些店,OK開始我們的例子:
基本界面如下:
當點擊搜索周邊團購時,將以西單廣場為中心,搜索其周邊1000米范圍內的餐飲團購,最終效果如下圖:
我們來看下核心代碼:
點擊搜索周邊按鈕對周邊進行查詢:
public void onClick(View v) { mCurrentPage = 0; // 搜索北京市內的餐飲 mQuery = new Query("", "餐飲", "010"); // 每頁顯示10條結果 mQuery.setPageSize(10); // 查詢的頁數 mQuery.setPageNum(mCurrentPage); // 有團購 mQuery.setLimitGroupbuy(true); mPoiSearch = new PoiSearch(getApplicationContext(), mQuery); // 搜索設置的中心周圍1000米范圍內的團購 mPoiSearch.setBound(new SearchBound(mSearchCenterPoint, 1000, true)); mPoiSearch.setOnPoiSearchListener(getOnPoiSearchListener()); mPoiSearch.searchPOIAsyn(); }
在查詢結果中進行如下處理:
/** * 處理poi搜索結果 */ private void processPoiSearchResult(PoiResult poiResult, int resultCode) { if (resultCode == 0) { if (poiResult != null && poiResult.getQuery() != null) {// 搜索poi的結果 List<PoiItem> poiItems = poiResult.getPois();// 取得poiitem數據 if (poiItems != null && poiItems.size() > 0) { mAMap.clear();// 清理之前的圖標 //繼承自PoiOverlay ViewPoiOverlay poiOverlay = new ViewPoiOverlay(mAMap, poiItems, getApplicationContext()); poiOverlay.removeFromMap(); poiOverlay.addToMap(); poiOverlay.zoomToSpan(); mNextPageButton.setClickable(true);// 設置下一頁可點 } } } }
其中ViewPoiOverlay是繼承自PoiOverlay類,主要重寫了getBitmapDescriptor(int index)方法。
protected BitmapDescriptor getBitmapDescriptor(int index) { TextView textView = null; //緩存View,減少系統消耗 if (views.size() <= index || views.get(index) == null) { textView = new TextView(mContext); String tile = getTitle(index); textView.setText(tile); textView.setBackgroundResource(R.drawable.custom_info_bubble); textView.setTextColor(Color.BLACK); textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 15); views.add(textView); } else { textView = (TextView) views.get(index); String tile = getTitle(index); textView.setText(tile); } return BitmapDescriptorFactory.fromView(textView); }
PS:其實根據這個例子去發散思路,對於這個效果我們還可以有不同思路去實現,也可以實現更多效果。例如我們可以fromBitmap()的方式去實例化一個BitmapDescriptor,這樣我們就可以用Canvas進行繪制,繪制出自己需要的圖形和樣式來作為Marker添加到地圖上。這樣這個Marker就可以有無數可能,大家可以充分發揮想象力去實現想要的效果了。