You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Studio中如何将Google Maps标记的信息窗置于左右侧?求安卓实现

实现Google Maps Marker InfoWindow显示在左侧/右侧的方法

嘿,我刚好折腾过这个需求!Android版的Google Maps SDK确实没有直接让你把InfoWindow放到Marker左右侧的现成API,但咱们可以通过自定义InfoWindow+调整偏移量的方式搞定,亲测有效~

步骤1:自定义InfoWindow布局

首先你需要创建一个自定义的InfoWindow布局,替换默认的样式。比如在res/layout/下新建info_window_custom.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@drawable/info_window_bg" <!-- 可自定义背景形状/颜色 -->
    android:orientation="vertical"
    android:padding="12dp">

    <TextView
        android:id="@+id/tv_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textColor="#000000"
        android:textSize="16sp"
        android:textStyle="bold" />

    <TextView
        android:id="@+id/tv_snippet"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textColor="#666666"
        android:textSize="14sp" />

</LinearLayout>

步骤2:实现InfoWindowAdapter

接下来在你的Activity/Fragment里,给GoogleMap设置自定义的InfoWindowAdapter,用来加载我们刚才的布局:

// 假设你已经通过onMapReady获取到了GoogleMap实例mMap
mMap.setInfoWindowAdapter(object : GoogleMap.InfoWindowAdapter {
    override fun getInfoWindow(marker: Marker): View? {
        // 加载自定义布局
        val infoView = LayoutInflater.from(this@MainActivity)
            .inflate(R.layout.info_window_custom, null)
        
        // 填充Marker的标题和详情内容
        infoView.findViewById<TextView>(R.id.tv_title).text = marker.title
        infoView.findViewById<TextView>(R.id.tv_snippet).text = marker.snippet
        
        return infoView
    }

    override fun getInfoContents(marker: Marker): View? {
        // 这里返回null,因为我们用getInfoWindow返回了完整的自定义View
        return null
    }
})

步骤3:计算并设置InfoWindow偏移量

这是核心步骤!默认InfoWindow会显示在Marker的正上方,我们需要计算偏移量,把它挪到左侧或右侧:

// 监听InfoWindow显示事件,动态计算偏移
mMap.setOnInfoWindowShownListener { marker ->
    val infoWindowView = mMap.infoWindowAdapter.getInfoWindow(marker) ?: return@setOnInfoWindowShownListener
    
    // 先测量InfoWindow的实际宽高(因为布局是wrap_content,需要先测量才能拿到准确值)
    infoWindowView.measure(
        View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
        View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)
    )
    val infoWindowWidth = infoWindowView.measuredWidth
    val infoWindowHeight = infoWindowView.measuredHeight

    // 获取Marker图标的实际宽高(如果是自定义Marker,用这个更准确)
    val markerIconWidth = marker.icon?.intrinsicWidth ?: resources.getDimensionPixelSize(R.dimen.default_marker_width)
    val markerIconHeight = marker.icon?.intrinsicHeight ?: resources.getDimensionPixelSize(R.dimen.default_marker_height)

    // 计算X偏移:
    // - 右侧偏移:InfoWindow一半宽度 + Marker图标一半宽度(让InfoWindow和Marker图标刚好挨着)
    // - 左侧偏移:负的上述数值(把InfoWindow挪到Marker左边)
    val xOffset = if (true) { // 这里替换成你的判断逻辑,比如根据Marker类型决定左右
        (infoWindowWidth / 2) + (markerIconWidth / 2)
    } else {
        -((infoWindowWidth / 2) + (markerIconWidth / 2))
    }

    // Y偏移:保持默认的垂直居中(InfoWindow底部和Marker顶部对齐,可根据需求调整)
    val yOffset = -(infoWindowHeight / 2 + markerIconHeight / 2)

    // 给当前Marker设置InfoWindow偏移
    marker.setInfoWindowOffset(xOffset, yOffset)
}

额外注意事项

  • 如果你用的是默认Marker图标,可以提前在res/values/dimens.xml里定义默认宽高:
    <dimen name="default_marker_width">48dp</dimen>
    <dimen name="default_marker_height">48dp</dimen>
    
  • 每个Marker的InfoWindow偏移是独立的,如果你有多个Marker需要设置左右位置,可以在添加Marker的时候就计算好偏移,或者统一在监听器里处理。
  • 如果需要让InfoWindow支持交互(比如点击按钮),默认的InfoWindow是静态的,你需要结合PopupWindow来实现,但那是更复杂的场景,单纯调整位置的话上面的方法完全够用。

内容的提问来源于stack exchange,提问作者Rahul RAO

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 07:18:30