如何引用在 Android 片段中创建的地图

How to reference map created in Android Fragment

我正在遵循本指南: https://developers.google.com/codelabs/maps-platform/maps-platform-101-android#9

我正在尝试获取片段中的地图。我的地图已成功运行,但现在当地图打开时,它默认以真正高级别的视图显示非洲。我希望地图默认在更本地的级别打开我的城市。

我的 xml 片段文件如下所示:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".ViewNearbyFragment">

    <androidx.fragment.app.FragmentContainerView
        xmlns:map="http://schemas.android.com/apk/res-auto"
        class="com.google.android.gms.maps.SupportMapFragment"
        map:mapId="{my_map_id}"
        android:id="@+id/map_fragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</FrameLayout>

而对应于同一片段的 Kotlin 文件如下所示:

class ViewNearbyFragment : Fragment() {
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        (fragmentManager?.findFragmentById(
            R.id.map_fragment
        ) as? SupportMapFragment)?.getMapAsync { googleMap ->
            
            // Ensure all places are visible in the map.
            googleMap.setOnMapLoadedCallback {
                val bounds = LatLngBounds.builder()
                bounds.include(LatLng(0.0, 0.0))
                googleMap.moveCamera(CameraUpdateFactory.newLatLngBounds(bounds.build(), 20))
            }
        }
    }

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_view_nearby, container, false)
    }
}

我从不进入 getMapAsync 调用之后的块,我不确定为什么。如何访问在 xml 文件中创建的地图?或者更好的是,如何更改与此地图关联的默认值?

您的代码有两个问题:

    根据 Fragment lifecycle guide
  1. onCreate() 运行 秒前 onCreateView。这意味着当您的 onCreate 代码 运行 时,您的 FragmentContainerView 尚未膨胀(并且您的 SupportFragmentFragment 尚未创建)。 onCreateView 之后要 运行 的代码应移至 onViewCreated().

  2. 您使用了错误的 FragmentManager - 已弃用的 fragmentManager 是片段所附加的 FragmentManager (这就是为什么它被弃用的原因,因为更具描述性 parentFragmentManager名字)。您创建的片段是 'child fragment'(根据 FragmentManager guide),因此您需要使用 childFragmentManager.

您的固定代码如下所示:

class ViewNearbyFragment : Fragment() {

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_view_nearby, container, false)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {

        (childFragmentManager.findFragmentById(
            R.id.map_fragment
        ) as? SupportMapFragment)?.getMapAsync { googleMap ->
            
            // Ensure all places are visible in the map.
            googleMap.setOnMapLoadedCallback {
                val bounds = LatLngBounds.builder()
                bounds.include(LatLng(0.0, 0.0))
                googleMap.moveCamera(CameraUpdateFactory.newLatLngBounds(bounds.build(), 20))
            }
        }
    }
}