百度地圖SDK Android版開發(fā) 10 InfoWindow

前言

前文介紹百度地圖添加Marker的使用方法,Marker結(jié)合InfoWindow可展示更詳盡的信息。本文將介紹以下內(nèi)容:

  1. 構(gòu)造InfoWindow對象的兩種方式;
  2. 地圖類顯示和隱藏InfoWindow的方法;
  3. 自定義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顯示的信息通過MarkerOptionsextraInfo傳遞。

界面布局

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)建與移除覆蓋物

  • 批量添加覆蓋物笛坦,通過MarkerOptionsextraInfo区转,向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
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末版扩,一起剝皮案震驚了整個(gè)濱河市废离,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌礁芦,老刑警劉巖蜻韭,帶你破解...
    沈念sama閱讀 218,036評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異宴偿,居然都是意外死亡湘捎,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,046評論 3 395
  • 文/潘曉璐 我一進(jìn)店門窄刘,熙熙樓的掌柜王于貴愁眉苦臉地迎上來窥妇,“玉大人,你說我怎么就攤上這事娩践』铘妫” “怎么了?”我有些...
    開封第一講書人閱讀 164,411評論 0 354
  • 文/不壞的土叔 我叫張陵翻伺,是天一觀的道長材泄。 經(jīng)常有香客問我,道長吨岭,這世上最難降的妖魔是什么拉宗? 我笑而不...
    開封第一講書人閱讀 58,622評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮辣辫,結(jié)果婚禮上旦事,老公的妹妹穿的比我還像新娘。我一直安慰自己急灭,他們只是感情好姐浮,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,661評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著葬馋,像睡著了一般卖鲤。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上畴嘶,一...
    開封第一講書人閱讀 51,521評論 1 304
  • 那天蛋逾,我揣著相機(jī)與錄音,去河邊找鬼窗悯。 笑死区匣,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的蟀瞧。 我是一名探鬼主播沉颂,決...
    沈念sama閱讀 40,288評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼悦污!你這毒婦竟也來了铸屉?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,200評論 0 276
  • 序言:老撾萬榮一對情侶失蹤切端,失蹤者是張志新(化名)和其女友劉穎彻坛,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體踏枣,經(jīng)...
    沈念sama閱讀 45,644評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡昌屉,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,837評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了茵瀑。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片间驮。...
    茶點(diǎn)故事閱讀 39,953評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖马昨,靈堂內(nèi)的尸體忽然破棺而出竞帽,到底是詐尸還是另有隱情,我是刑警寧澤鸿捧,帶...
    沈念sama閱讀 35,673評論 5 346
  • 正文 年R本政府宣布屹篓,位于F島的核電站,受9級特大地震影響匙奴,放射性物質(zhì)發(fā)生泄漏堆巧。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,281評論 3 329
  • 文/蒙蒙 一泼菌、第九天 我趴在偏房一處隱蔽的房頂上張望谍肤。 院中可真熱鬧,春花似錦灶轰、人聲如沸谣沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,889評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽乳附。三九已至,卻和暖如春伴澄,著一層夾襖步出監(jiān)牢的瞬間赋除,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,011評論 1 269
  • 我被黑心中介騙來泰國打工非凌, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留举农,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,119評論 3 370
  • 正文 我出身青樓敞嗡,卻偏偏與公主長得像颁糟,于是被迫代替她去往敵國和親航背。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,901評論 2 355

推薦閱讀更多精彩內(nèi)容