百度地图SDK Android版开发 10 InfoWindow

前言

前文介绍百度地图添加Marker的使用方法,Marker结合InfoWindow可用展示更详尽的信息。本文将介绍以下内容:

  1. 构造InfoWindow对象的两种方式;
  2. 地图类显示和隐藏InfoWindow的方法;
  3. 自定义InfoWindowAdapter类,通过Marker显示InfoWindow

InfoWindow 相关类和接口

BaiduMap类

类型方法说明
List< InfoWindow >getAllInfoWindows()5.4.0版本新增接口 获取已添加的所有InfoWindow对象
voidshowInfoWindow(InfoWindow infoWindow)显示 InfoWindow,。
该接口会先隐藏其他已添加的InfoWindow, 再添加新的InfoWindow
voidshowInfoWindow(InfoWindow infoWindow, boolean isHideOthers)5.4.0版本新增接口 显示 InfoWindow。
该接口可以设置是否在添加InfoWindow之前,先隐藏其他已经添加的InfoWindow.
voidshowInfoWindows(List< InfoWindow > infoWindowList)5.4.0版本新增接口 添加多个InfoWindow
voidhideInfoWindow()隐藏地图上的所有InfoWindow
voidhideInfoWindow(InfoWindow infoWindow)5.4.0版本新增接口 清除特定的InfoWindow
voidclear()清空地图所有的 Overlay 覆盖物以及 InfoWindow

InfoWindow 类

构造方法

在地图中显示一个信息窗口,可以设置一个View作为该窗口的内容,也可以设置一个 BitmapDescriptor 作为该窗口的内容。

方式一:通过添加View在地图上展示,交互操作通过View实现。

方式二:将View转化为Bitmap渲染在地图上,交互操作通过InfoWindow实现。这种方法性能比第一种方法要高。

方法说明
InfoWindow(BitmapDescriptor bd, LatLng position, int yOffset, InfoWindow.OnInfoWindowClickListener listener)通过传入的 BitmapDescriptor 构造一个 InfoWindow。
参数:
bd - **InfoWindow 展示的bitmap
**position - InfoWindow 显示的地理位置
yOffset - InfoWindow Y 轴偏移量
listener - InfoWindow 点击监听者
InfoWindow(View view, LatLng position, int yOffset)通过传入的 view 构造一个 InfoWindow, 此时只是利用该view生成一个Bitmap绘制在地图中,监听事件由开发者实现。
**参数:
**view - **InfoWindow 展示的 view
**position - InfoWindow 显示的地理位置
yOffset - InfoWindow Y 轴偏移量
InfoWindow(View view, LatLng position, int yOffset, boolean isFitDensityDpi, int targetDensityDpi)根据指定的像素密度对传入的view构造InfoWindow, 此时只是利用该view生成一个Bitmap绘制在地图中,监听事件由开发者实现。
参数:
view - InfoWindow 展示的 view
position - InfoWindow 显示的地理位置
yOffset - InfoWindow Y 轴偏移量
isFitDensityDpi - 是否适配设备像素密度,默认不适配
targetDensityDpi - 目标像素密度, 建议传入设备默认像素密度值,否则可能会展示效果无法到达预期

getter

类型方法说明
BitmapDescriptorgetBitmapDescriptor()获取InfoWindow的BitmapDescriptor资源
LatLnggetPosition()获取位置数据
StringgetTag()获取InfoWindow的Tag
ViewgetView()获取InfoWindow的View
intgetYOffset()获取InfoWindow的YOffset偏移

setter

类型方法说明
voidsetBitmapDescriptor(BitmapDescriptor mBitmapDescriptor)更新InfoWindow的BitmapDescriptor属性。
voidsetPosition(LatLng mPosition)设置位置数据
voidsetTag(String tag)设置InfoWindow的Tag
voidsetView(View mView)更新InfoWindow的View属性 注: 仅支持通过InfoWindow(View, LatLng, int, boolean, int) or InfoWindow(View, LatLng, int)两种方式创建 InfoWindow的更新; 如果是使用了InfoWindow(BitmapDescriptor, LatLng, int, OnInfoWindowClickListener)方式创建的 InfoWindow,则不要使用该接口更新View属性,否则可能出现View与BitmapDescriptor层叠的现象。
voidsetYOffset(int mYOffset)设置InfoWindow的YOffset偏移

OnInfoWindowClickListener 接口

// 信息窗口点击事件监听接口
public interface OnInfoWindowClickListener {
    // 信息窗口点击事件处理函数
    void onInfoWindowClick();
}

InfoWindowAdapter 相关类和方法

自定义适配器InfoWindowAdapter并设置map.setInfoWindowAdapter(adapter),调用marker.showInfoWindow()即可实现显示InfoWindow

BaiduMap类

类型方法说明
voidsetInfoWindowAdapter(InfoWindowAdapter adapter)设置InfoWindowAdapter

InfoWindowAdapter 接口

public interface InfoWindowAdapter {
    View getInfoWindowView(Marker marker);

    int getInfoWindowViewYOffset();

    InfoWindow getInfoWindow(Marker marker);
}

Marker 类

Marker中的InfoWindow方法

类型方法说明
voidshowInfoWindow()添加 Marker 关联的InfoWindow,两者的更新是相互独立的。
类型方法说明
booleanisInfoWindowEnabled()判断是否显示InfoWindow
InfoWindowgetInfoWindow()获取 Marker 绑定的InfoWindow
voidsetPositionWithInfoWindow(LatLng position)设置 Marker 覆盖物的位置坐标,并同步更新与Marker关联的InfoWindow的位置坐标.
voidshowInfoWindow(InfoWindow mInfoWindow)添加 Marker 关联的InfoWindow,两者的更新是相互独立的。
voidshowSmoothMoveInfoWindow(InfoWindow mInfoWindow)该接口适用于小车平滑移动中,InfoWindow需要跟随 Marker 频繁动态更新View属性的场景。
voidhideInfoWindow()移除与 Marker 绑定的InfoWindow
voidupdateInfoWindowBitmapDescriptor(BitmapDescriptor bitmapDescriptor)更新与Marker绑定的InfoWindow对应的BitmapDescriptor,适用于以BitmapDescriptor方式创建InfoWindow 注: 仅支持通过InfoWindow.InfoWindow(BitmapDescriptor, LatLng, int, InfoWindow.OnInfoWindowClickListener) 方式创建的InfoWindow的更新;
voidupdateInfoWindowPosition(LatLng position)更新与Marker绑定的InfoWindow对应的位置
voidupdateInfoWindowView(View view)更新与Marker绑定的InfoWindow对应的View,适用于以View方式创建InfoWindow 注: 仅支持通过InfoWindow.InfoWindow(View, LatLng, int, boolean, int) or InfoWindow.InfoWindow(View, LatLng, int)两种方式创建的InfoWindow的更新;
voidupdateInfoWindowYOffset(int yOffset)更新与Marker绑定的InfoWindow对应的yOffset

示例

在地图上显示多个Marker覆盖物,点击Marker显示InfoWindow。其中InfoWindow显示的信息通过MarkerOptionsextraInfo传递。

界面布局

在这里插入图片描述

  • 布局文件
<?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<>();
// 选中的状态
String selectedFlag = VIEW_MODE;
// 气泡图标
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());
  • 点击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;
        }
    });
}

创建与移除覆盖物

  • 批量添加覆盖物,通过MarkerOptionsextraInfo,向InfoWindow传递数据。
public void addMarkers() {
    // 构造大量坐标数据
    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));

    // 创建OverlayOptions的集合
    List<OverlayOptions> optionsList = new ArrayList<>();
    for (int i = 0; i < points.size(); ++i) {
        // 创建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() {
    // 批量删除添加的多个 Overlay
    //map.removeOverLays(overlays);

    // 清空地图所有的 Overlay 覆盖物以及 InfoWindow
    // map.clear();

    // 删除覆盖物
    for (Overlay overlay : overlays) {
        overlay.remove();
    }
    overlays.clear();
}

显示与隐藏InfowWindow

  • 视图模式
// 使用View构造InfoWindow
private void showViewMode(Marker marker) {
    LatLng latLng = marker.getPosition();
    int id = marker.getExtraInfo().getInt("id");

    // 用来构造InfoWindow的Button
    Button button = new Button(context);
    button.setBackgroundResource(R.drawable.popup);
    button.setText("View示例-" + id);
    button.setTextColor(Color.BLACK);
    // 监听点击事件
    button.setOnClickListener(new View.OnClickListener() {
        public void onClick(View v) {
            map.hideInfoWindow();
        }
    });

    // 创建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点击事件监听接口
    InfoWindow.OnInfoWindowClickListener listener;
    // 监听点击事件
    listener = new InfoWindow.OnInfoWindowClickListener() {
        public void onInfoWindowClick() {
            // 隐藏地图上的所有InfoWindow
            map.hideInfoWindow();
        }
    };

    // 创建InfoWindow
    InfoWindow infoWindow = new InfoWindow(bitmap, latLng, yOffset, listener);
    // 显示InfoWindow
    map.showInfoWindow(infoWindow);
}
  • 适配器模式
private void showAdapterMode(Marker marker) {
    // 避免同时显示多个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点击事件监听接口
        InfoWindow.OnInfoWindowClickListener listener;
        listener = new InfoWindow.OnInfoWindowClickListener() {
            public void onInfoWindowClick() {
                map.hideInfoWindow();
            }
        };

        // 创建InfoWindow
        return new InfoWindow(bitmap, latLng, yOffset, listener);
    }
}

设置属性

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类部分代码

控件响应事件

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);
}

运行效果图

在这里插入图片描述

  • 18
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值