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"
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?
CodePudding user response:
There's two problems with your code:
onCreate()
runs beforeonCreateView
as per the Fragment lifecycle guide. This means that yourFragmentContainerView
hasn't been inflated (and yourSupportFragmentFragment
hasn't been created) when youronCreate
code runs. Code you want to run afteronCreateView
should be moved toonViewCreated()
.You're using the wrong FragmentManager - the deprecated
fragmentManager
is theFragmentManager
that the fragment is attached to (that's why it was deprecated for the much more descriptiveparentFragmentManager
name). 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))
}
}
}
}