I am following this guide:
https://developers.google.com/codelabs/maps-platform/maps-platform-101-android#9
and I am trying to get a map in a fragment. I have the map successfully working but right now when the map opens, it defaults to showing Africa at a really high-level view. I want the map to default to opening to my City at a much more local level.
My xml file for the fragment looks like:
<?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>
And the Kotlin file corresponding to the same fragment looks like:
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)
}
}
I am never entering the block that follows the getMapAsync call and I am not sure why. How can I access the map that was created in the xml file? or better yet, how can I change default values associated with this map?
>Solution :
There’s two problems with your code:
-
onCreate()runs beforeonCreateViewas per the Fragment lifecycle guide. This means that yourFragmentContainerViewhasn’t been inflated (and yourSupportFragmentFragmenthasn’t been created) when youronCreatecode runs. Code you want to run afteronCreateViewshould be moved toonViewCreated(). -
You’re using the wrong FragmentManager – the deprecated
fragmentManageris theFragmentManagerthat the fragment is attached to (that’s why it was deprecated for the much more descriptiveparentFragmentManagername). The fragment you’ve created is a ‘child fragment’ (as per the FragmentManager guide) so you need to use thechildFragmentManager.
Your fixed code would look like:
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))
}
}
}
}