前言
前文介紹百度地圖添加Marker
的使用方法,Marker
結(jié)合InfoWindow
可展示更詳盡的信息。本文將介紹以下內(nèi)容:
- 構(gòu)造
InfoWindow
對象的兩種方式; - 地圖類顯示和隱藏
InfoWindow
的方法; - 自定義
InfoWindowAdapter
類吗浩,通過Marker
顯示InfoWindow
。
InfoWindow 相關(guān)類和接口
BaiduMap類
類型 | 方法 | 說明 |
---|---|---|
List< InfoWindow > |
getAllInfoWindows () |
5.4.0版本新增接口 獲取已添加的所有InfoWindow對象 |
void |
showInfoWindow (InfoWindow infoWindow) |
顯示 InfoWindow,没隘。 該接口會先隱藏其他已添加的InfoWindow, 再添加新的InfoWindow |
void |
showInfoWindow (InfoWindow infoWindow, boolean isHideOthers) |
5.4.0版本新增接口 顯示 InfoWindow懂扼。 該接口可以設(shè)置是否在添加InfoWindow之前,先隱藏其他已經(jīng)添加的InfoWindow. |
void |
showInfoWindows (List< InfoWindow > infoWindowList) |
5.4.0版本新增接口 添加多個(gè)InfoWindow |
void |
hideInfoWindow () |
隱藏地圖上的所有InfoWindow |
void |
hideInfoWindow (InfoWindow infoWindow) |
5.4.0版本新增接口 清除特定的InfoWindow |
void |
clear () |
清空地圖所有的 Overlay 覆蓋物以及 InfoWindow |
InfoWindow 類
構(gòu)造方法
在地圖中顯示一個(gè)信息窗口右蒲,可以設(shè)置一個(gè)View
作為該窗口的內(nèi)容阀湿,也可以設(shè)置一個(gè) BitmapDescriptor
作為該窗口的內(nèi)容。
方式一:通過添加View
在地圖上展示瑰妄,交互操作通過View
實(shí)現(xiàn)陷嘴。
方式二:將View
轉(zhuǎn)化為Bitmap
渲染在地圖上,交互操作通過InfoWindow
實(shí)現(xiàn)间坐。這種方法性能比第一種方法要高灾挨。
方法 | 說明 |
---|---|
InfoWindow (BitmapDescriptor bd, LatLng position, int yOffset, InfoWindow.OnInfoWindowClickListener listener) |
通過傳入的 BitmapDescriptor 構(gòu)造一個(gè) InfoWindow。 參數(shù): bd - InfoWindow 展示的bitmap position - InfoWindow 顯示的地理位置 yOffset - InfoWindow Y 軸偏移量 listener - InfoWindow 點(diǎn)擊監(jiān)聽者 |
InfoWindow (View view, LatLng position, int yOffset) |
通過傳入的 view 構(gòu)造一個(gè) InfoWindow, 此時(shí)只是利用該view生成一個(gè)Bitmap繪制在地圖中竹宋,監(jiān)聽事件由開發(fā)者實(shí)現(xiàn)劳澄。 參數(shù): view - InfoWindow 展示的 view position - InfoWindow 顯示的地理位置 yOffset - InfoWindow Y 軸偏移量 |
InfoWindow (View view, LatLng position, int yOffset, boolean isFitDensityDpi, int targetDensityDpi) |
根據(jù)指定的像素密度對傳入的view構(gòu)造InfoWindow, 此時(shí)只是利用該view生成一個(gè)Bitmap繪制在地圖中,監(jiān)聽事件由開發(fā)者實(shí)現(xiàn)逝撬。 參數(shù): view - InfoWindow 展示的 view position - InfoWindow 顯示的地理位置 yOffset - InfoWindow Y 軸偏移量 isFitDensityDpi - 是否適配設(shè)備像素密度浴骂,默認(rèn)不適配 targetDensityDpi - 目標(biāo)像素密度, 建議傳入設(shè)備默認(rèn)像素密度值,否則可能會展示效果無法到達(dá)預(yù)期 |
getter
類型 | 方法 | 說明 |
---|---|---|
BitmapDescriptor |
getBitmapDescriptor () |
獲取InfoWindow的BitmapDescriptor資源 |
LatLng |
getPosition () |
獲取位置數(shù)據(jù) |
String |
getTag () |
獲取InfoWindow的Tag |
View |
getView () |
獲取InfoWindow的View |
int |
getYOffset () |
獲取InfoWindow的YOffset偏移 |
setter
類型 | 方法 | 說明 |
---|---|---|
void |
setBitmapDescriptor (BitmapDescriptor mBitmapDescriptor) |
更新InfoWindow的BitmapDescriptor屬性宪潮。 |
void |
setPosition (LatLng mPosition) |
設(shè)置位置數(shù)據(jù) |
void |
setTag (String tag) |
設(shè)置InfoWindow的Tag |
void |
setView (View mView) |
更新InfoWindow的View屬性 注: 僅支持通過InfoWindow(View, LatLng, int, boolean, int) or InfoWindow(View, LatLng, int)兩種方式創(chuàng)建 InfoWindow的更新; 如果是使用了InfoWindow(BitmapDescriptor, LatLng, int, OnInfoWindowClickListener)方式創(chuàng)建的 InfoWindow溯警,則不要使用該接口更新View屬性,否則可能出現(xiàn)View與BitmapDescriptor層疊的現(xiàn)象狡相。 |
void |
setYOffset (int mYOffset) |
設(shè)置InfoWindow的YOffset偏移 |
OnInfoWindowClickListener 接口
// 信息窗口點(diǎn)擊事件監(jiān)聽接口
public interface OnInfoWindowClickListener {
// 信息窗口點(diǎn)擊事件處理函數(shù)
void onInfoWindowClick();
}
InfoWindowAdapter 相關(guān)類和方法
自定義適配器InfoWindowAdapter
并設(shè)置map.setInfoWindowAdapter(adapter)
梯轻,調(diào)用marker.showInfoWindow()
即可實(shí)現(xiàn)顯示InfoWindow
。
BaiduMap類
類型 | 方法 | 說明 |
---|---|---|
void |
setInfoWindowAdapter (InfoWindowAdapter adapter) |
設(shè)置InfoWindowAdapter |
InfoWindowAdapter 接口
public interface InfoWindowAdapter {
View getInfoWindowView(Marker marker);
int getInfoWindowViewYOffset();
InfoWindow getInfoWindow(Marker marker);
}
Marker 類
Marker
中的InfoWindow
方法
類型 | 方法 | 說明 |
---|---|---|
void |
showInfoWindow () |
添加 Marker 關(guān)聯(lián)的InfoWindow,兩者的更新是相互獨(dú)立的尽棕。 |
類型 | 方法 | 說明 |
---|---|---|
boolean | isInfoWindowEnabled() | 判斷是否顯示InfoWindow |
InfoWindow | getInfoWindow() | 獲取 Marker 綁定的InfoWindow |
void | setPositionWithInfoWindow(LatLng position) | 設(shè)置 Marker 覆蓋物的位置坐標(biāo),并同步更新與Marker關(guān)聯(lián)的InfoWindow的位置坐標(biāo). |
void | showInfoWindow(InfoWindow mInfoWindow) | 添加 Marker 關(guān)聯(lián)的InfoWindow,兩者的更新是相互獨(dú)立的喳挑。 |
void | showSmoothMoveInfoWindow(InfoWindow mInfoWindow) | 該接口適用于小車平滑移動中,InfoWindow需要跟隨 Marker 頻繁動態(tài)更新View屬性的場景滔悉。 |
void | hideInfoWindow() | 移除與 Marker 綁定的InfoWindow |
void | updateInfoWindowBitmapDescriptor(BitmapDescriptor bitmapDescriptor) | 更新與Marker綁定的InfoWindow對應(yīng)的BitmapDescriptor伊诵,適用于以BitmapDescriptor方式創(chuàng)建InfoWindow 注: 僅支持通過InfoWindow.InfoWindow(BitmapDescriptor, LatLng, int, InfoWindow.OnInfoWindowClickListener) 方式創(chuàng)建的InfoWindow的更新; |
void | updateInfoWindowPosition(LatLng position) | 更新與Marker綁定的InfoWindow對應(yīng)的位置 |
void | updateInfoWindowView(View view) | 更新與Marker綁定的InfoWindow對應(yīng)的View,適用于以View方式創(chuàng)建InfoWindow 注: 僅支持通過InfoWindow.InfoWindow(View, LatLng, int, boolean, int) or InfoWindow.InfoWindow(View, LatLng, int)兩種方式創(chuàng)建的InfoWindow的更新; |
void | updateInfoWindowYOffset(int yOffset) | 更新與Marker綁定的InfoWindow對應(yīng)的yOffset |
示例
在地圖上顯示多個(gè)Marker
覆蓋物回官,點(diǎn)擊Marker
顯示InfoWindow
曹宴。其中InfoWindow
顯示的信息通過MarkerOptions
的extraInfo
傳遞。
界面布局
1-布局.png
- 布局文件
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.baidudemo.MapInfoWindowActivity">
<com.baidu.mapapi.map.MapView
android:id="@+id/bmapView"
android:layout_width="match_parent"
android:layout_height="0dp"
android:clickable="true"
app:layout_constraintBottom_toTopOf="@id/bottomView"
app:layout_constraintTop_toTopOf="parent" />
<androidx.appcompat.widget.LinearLayoutCompat
android:id="@+id/bottomView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="@id/bmapView">
<RadioGroup
android:id="@+id/RadioGroup"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/background_dark"
android:gravity="center_horizontal"
android:orientation="horizontal"
android:paddingHorizontal="10dp">
<RadioButton
android:id="@+id/viewMode"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:checked="true"
android:onClick="setMarkerFlag"
android:text="View Mode"
android:textColor="@color/white"
android:textStyle="bold" />
<RadioButton
android:id="@+id/bitmapMode"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:onClick="setMarkerFlag"
android:text="Bitmap Mode"
android:textColor="@color/white"
android:textStyle="bold" />
<RadioButton
android:id="@+id/adapter_mode"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:onClick="setMarkerFlag"
android:text="Adapter Mode"
android:textColor="@color/white"
android:textStyle="bold" />
</RadioGroup>
</androidx.appcompat.widget.LinearLayoutCompat>
</androidx.constraintlayout.widget.ConstraintLayout>
MapInfoWindow類
- 以下是
MapInfoWindow
部分代碼
常量
public static final String VIEW_MODE = "ViewMode";
public static final String BITMAP_MODE = "BitmapMode";
public static final String ADAPTER_MODE = "AdapterMode";
成員變量
// 覆蓋物列表
List<Overlay> overlays = new ArrayList<>();
// 選中的狀態(tài)
String selectedFlag = VIEW_MODE;
// 氣泡圖標(biāo)
ArrayList<BitmapDescriptor> bitmaps = new ArrayList<>();
int yOffset = 0; // InfoWindow相對于point在y軸的偏移量
初始化
int[] drawableIds = BubbleIcons.Number;
for (int drawableId : drawableIds) {
BitmapDescriptor bitmap = BitmapDescriptorFactory.fromResource(drawableId);
if (yOffset == 0)
yOffset = -bitmap.getBitmap().getHeight();
bitmaps.add(bitmap);
}
initEvent();
map.setInfoWindowAdapter(new MyInfoWindowAdapter());
- 點(diǎn)擊
Marker
顯示InfoWindow
歉提。
private void initEvent() {
map.setOnMarkerClickListener(new BaiduMap.OnMarkerClickListener() {
@Override
public boolean onMarkerClick(Marker marker) {
switch (selectedFlag) {
case VIEW_MODE:
showViewMode(marker);
break;
case BITMAP_MODE:
showBitmapMode(marker);
break;
case ADAPTER_MODE:
showAdapterMode(marker);
break;
}
return true;
}
});
}
創(chuàng)建與移除覆蓋物
- 批量添加覆蓋物笛坦,通過
MarkerOptions
的extraInfo
区转,向InfoWindow
傳遞數(shù)據(jù)。
public void addMarkers() {
// 構(gòu)造大量坐標(biāo)數(shù)據(jù)
List<LatLng> points = new ArrayList<>();
points.add(new LatLng(39.97923, 116.357428));
points.add(new LatLng(39.94923, 116.397428));
points.add(new LatLng(39.97923, 116.437428));
points.add(new LatLng(39.92353, 116.490705));
points.add(new LatLng(40.023537, 116.289429));
points.add(new LatLng(40.022211, 116.406137));
// 創(chuàng)建OverlayOptions的集合
List<OverlayOptions> optionsList = new ArrayList<>();
for (int i = 0; i < points.size(); ++i) {
// 創(chuàng)建OverlayOptions屬性
MarkerOptions option = new MarkerOptions()
.position(points.get(i))
.icon(bitmaps.get(i));
Bundle bundle = new Bundle();
bundle.putInt("id", i + 1);
option.extraInfo(bundle);
// 將OverlayOptions添加到list
optionsList.add(option);
}
// 在地圖上批量添加
List<Overlay> newOverlays = map.addOverlays(optionsList);
overlays.addAll(newOverlays);
}
public void removeOverlay() {
// 批量刪除添加的多個(gè) Overlay
//map.removeOverLays(overlays);
// 清空地圖所有的 Overlay 覆蓋物以及 InfoWindow
// map.clear();
// 刪除覆蓋物
for (Overlay overlay : overlays) {
overlay.remove();
}
overlays.clear();
}
顯示與隱藏InfowWindow
- 視圖模式
// 使用View構(gòu)造InfoWindow
private void showViewMode(Marker marker) {
LatLng latLng = marker.getPosition();
int id = marker.getExtraInfo().getInt("id");
// 用來構(gòu)造InfoWindow的Button
Button button = new Button(context);
button.setBackgroundResource(R.drawable.popup);
button.setText("View示例-" + id);
button.setTextColor(Color.BLACK);
// 監(jiān)聽點(diǎn)擊事件
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
map.hideInfoWindow();
}
});
// 創(chuàng)建InfoWindow
InfoWindow infoWindow = new InfoWindow(button, latLng, yOffset);
// 顯示InfoWindow
map.showInfoWindow(infoWindow);
}
- 位圖模式
private void showBitmapMode(Marker marker) {
LatLng latLng = marker.getPosition();
int id = marker.getExtraInfo().getInt("id");
Button button = new Button(context);
button.setBackgroundResource(R.drawable.popup);
button.setText("Bitmap示例-" + id);
button.setTextColor(Color.BLACK);
button.setWidth(400);
BitmapDescriptor bitmap = BitmapDescriptorFactory.fromView(button);
// InfoWindow點(diǎn)擊事件監(jiān)聽接口
InfoWindow.OnInfoWindowClickListener listener;
// 監(jiān)聽點(diǎn)擊事件
listener = new InfoWindow.OnInfoWindowClickListener() {
public void onInfoWindowClick() {
// 隱藏地圖上的所有InfoWindow
map.hideInfoWindow();
}
};
// 創(chuàng)建InfoWindow
InfoWindow infoWindow = new InfoWindow(bitmap, latLng, yOffset, listener);
// 顯示InfoWindow
map.showInfoWindow(infoWindow);
}
- 適配器模式
private void showAdapterMode(Marker marker) {
// 避免同時(shí)顯示多個(gè)InfoWindow
map.hideInfoWindow();
marker.showInfoWindow();
}
- 自定義適配器
private class MyInfoWindowAdapter implements InfoWindowAdapter {
@Override
public View getInfoWindowView(Marker marker) {
return null;
}
@Override
public int getInfoWindowViewYOffset() {
return yOffset;
}
@Override
public InfoWindow getInfoWindow(Marker marker) {
LatLng latLng = marker.getPosition();
int id = marker.getExtraInfo().getInt("id");
Button button = new Button(context);
button.setBackgroundResource(R.drawable.popup);
button.setText("Adapter示例-" + id);
button.setTextColor(Color.BLACK);
button.setWidth(400);
BitmapDescriptor bitmap = BitmapDescriptorFactory.fromView(button);
// InfoWindow點(diǎn)擊事件監(jiān)聽接口
InfoWindow.OnInfoWindowClickListener listener;
listener = new InfoWindow.OnInfoWindowClickListener() {
public void onInfoWindowClick() {
map.hideInfoWindow();
}
};
// 創(chuàng)建InfoWindow
return new InfoWindow(bitmap, latLng, yOffset, listener);
}
}
設(shè)置屬性
public void setFlag(String flag) {
selectedFlag = flag;
// 隱藏地圖上的所有InfoWindow
map.hideInfoWindow();
}
加載與移除地圖
public void onMapLoaded() {
addMarkers();
setFlag(VIEW_MODE);
}
public void onMapDestroy() {
removeOverlay();
for (BitmapDescriptor bitmap : bitmaps) {
bitmap.recycle();
}
bitmaps = null;
}
MapInfoWindowActivity 類
- 以下是
MapInfoWindowActivity
類部分代碼
控件響應(yīng)事件
public void setMarkerFlag(View view) {
boolean checked = ((RadioButton) view).isChecked();
if (!checked)
return;
int id = view.getId();
String flag;
if (id == R.id.viewMode)
flag = MapInfoWindow.VIEW_MODE;
else if (id == R.id.bitmapMode)
flag = MapInfoWindow.BITMAP_MODE;
else if (id == R.id.adapter_mode)
flag = MapInfoWindow.ADAPTER_MODE;
else
return;
mapInfoWindow.setFlag(flag);
}
運(yùn)行效果圖
2-效果圖.png