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

如何在Android API 28中将SupportMapFragment设置为圆形?

解决API 28下SupportMapFragment设置圆形的问题

问题原因

直接给FragmentContainerView或SupportMapFragment的View设置clipToOutline无效,主要有两个原因:

  1. XML中的android:clipToOutline属性需要API 32及以上才支持,API 28无法通过XML生效;
  2. SupportMapFragment底层依赖SurfaceView,低版本系统中SurfaceView对clipToOutline的支持存在兼容性问题,直接设置无法完成裁剪。

方案一:用CardView作为父容器(推荐)

CardView的圆角裁剪是自身实现的,不依赖系统API,兼容性更好,实现起来也最简单:

修改布局文件:

<androidx.cardview.widget.CardView
    android:id="@+id/mapContainer"
    android:layout_width="200dp"
    android:layout_height="200dp"
    android:layout_marginTop="16dp"
    app:cardCornerRadius="100dp" <!-- 圆角半径设为宽高的一半,实现圆形 -->
    app:cardElevation="0dp" <!-- 不需要阴影可以设为0 -->
    app:layout_constraintEnd_toEndOf="@id/pulsatingCircle"
    app:layout_constraintStart_toStartOf="@id/pulsatingCircle"
    app:layout_constraintTop_toTopOf="@id/pulsatingCircle">

    <androidx.fragment.app.FragmentContainerView
        android:id="@+id/customerMapView"
        android:name="com.google.android.gms.maps.SupportMapFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:contentDescription="@string/customer_map_view" />
</androidx.cardview.widget.CardView>

无需额外Kotlin代码,CardView会自动将内部的地图裁剪为圆形。

方案二:自定义父布局的OutlineProvider

如果不想用CardView,可以给父布局设置自定义的圆形轮廓,再开启裁剪:

  1. 修改布局文件,给FragmentContainerView套一层父布局:
<androidx.constraintlayout.widget.ConstraintLayout
    android:id="@+id/mapContainer"
    android:layout_width="200dp"
    android:layout_height="200dp"
    android:layout_marginTop="16dp"
    app:layout_constraintEnd_toEndOf="@id/pulsatingCircle"
    app:layout_constraintStart_toStartOf="@id/pulsatingCircle"
    app:layout_constraintTop_toTopOf="@id/pulsatingCircle">

    <androidx.fragment.app.FragmentContainerView
        android:id="@+id/customerMapView"
        android:name="com.google.android.gms.maps.SupportMapFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:contentDescription="@string/customer_map_view"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
  1. 在Kotlin代码中设置父布局的轮廓和裁剪:
private fun initMap() {
    val mapContainer = findViewById<ConstraintLayout>(R.id.mapContainer)
    // 设置圆形轮廓
    mapContainer.outlineProvider = object : ViewOutlineProvider() {
        override fun getOutline(view: View, outline: Outline) {
            val radius = view.width.coerceAtMost(view.height) / 2f
            outline.setRoundRect(0, 0, view.width, view.height, radius)
        }
    }
    mapContainer.clipToOutline = true

    // 初始化地图逻辑
    val mapView = supportFragmentManager.findFragmentById(R.id.customerMapView) as SupportMapFragment
    mapView.getMapAsync { googleMap ->
        // 处理地图初始化,比如设置地图样式、添加标记等
    }
}

注意事项

  • 确保父布局的宽高是正方形,否则裁剪出来会是椭圆形;
  • 方案二中要确保父布局已经完成测量(比如在onViewCreated或onResume中调用相关代码,避免宽高为0导致轮廓设置无效)。

内容的提问来源于stack exchange,提问作者Zachary Smouse

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 22:16:04