Reputation: 157
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?
Upvotes: 1
Views: 560
Reputation: 199825
There's two problems with your code:
onCreate()
runs before onCreateView
as per the Fragment lifecycle guide. This means that your FragmentContainerView
hasn't been inflated (and your SupportFragmentFragment
hasn't been created) when your onCreate
code runs. Code you want to run after onCreateView
should be moved to onViewCreated()
.
You're using the wrong FragmentManager - the deprecated fragmentManager
is the FragmentManager
that the fragment is attached to (that's why it was deprecated for the much more descriptive parentFragmentManager
name). The fragment you've created is a 'child fragment' (as per the FragmentManager guide) so you need to use the childFragmentManager
.
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))
}
}
}
}
Upvotes: 1