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
相关产品推荐
相关产品推荐

