大家都知道在高德地圖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就可以有無數可能,大家可以充分發揮想象力去實現想要的效果了。
