Multiple Surfaces¶
Setup¶
First, get an API key token, see the Getting Started guide.
Download the Maps & Navigation SDK for Android archive fileDownload the MultipleSurfacesInFragment project
archive file or clone the project with Git
See the Configure Android Example guide.
Run the example¶
In Android Studio, from the File
menu, select Sync Project with Gradle Files
Click NEXT
Click the green + in the lower right corner to add a fragment with a map.
How it works¶

You can open the MainActivity.kt file to see how to render multiple maps.
1// Kotlin code
2
3class FirstFragment : Fragment()
4{
5 override fun onCreateView(
6 inflater: LayoutInflater, container: ViewGroup?,
7 savedInstanceState: Bundle?
8 ): View? {
9 return inflater.inflate(R.layout.fragment_first, container, false)
10 }
11 override fun onViewCreated(view: View, savedInstanceState: Bundle?)
12 {
13 super.onViewCreated(view, savedInstanceState)
14 view.findViewById<Button>(R.id.button_first).setOnClickListener
15 {
16 findNavController().navigate(R.id.action_FirstFragment_to_SecondFragment)
17 }
18 }
19}
The first fragment.
1class SecondFragment : Fragment()
2{
3 private val maps = mutableMapOf<Long, MapView?>()
4 private val maxSurfacesCount = 9
5 override fun onCreateView(
6 inflater: LayoutInflater, container: ViewGroup?,
7 savedInstanceState: Bundle?
8 ): View? {
9 return inflater.inflate(R.layout.fragment_second, container, false)
10 }
11 override fun onViewCreated(view: View, savedInstanceState: Bundle?)
12 {
13 super.onViewCreated(view, savedInstanceState)
14 view.findViewById<Button>(R.id.button_second).setOnClickListener
15 {
16 findNavController().navigate(R.id.action_SecondFragment_to_FirstFragment)
17 }
18 val leftBtn = view.findViewById<FloatingActionButton>(R.id.bottomLeftButton)
19 leftBtn.visibility = View.VISIBLE
20 ButtonsDecorator.buttonAsDelete(requireContext(), leftBtn)
21 {
22 deleteLastSurface()
23 }
24 val rightBtn = view.findViewById<FloatingActionButton>(R.id.bottomRightButton)
25 rightBtn.visibility = View.VISIBLE
26 ButtonsDecorator.buttonAsAdd(requireContext(), rightBtn)
27 {
28 addSurface()
29 }
30 addSurface()
31 }
SecondFragment
also has a green + and a red x button to add or
remove maps, respectively, using the addSurface()
and
deleteLastSurface()
functions. 1 private fun addSurface()
2 {
3 val linearLayout = view?.findViewById<LinearLayout>(R.id.scrolledLinearLayout) ?: return
4 if (linearLayout.childCount >= maxSurfacesCount)
5 {
6 return
7 }
8 val surface = SdkCall.execute { GemSurfaceView(requireContext()) }
9 surface?.layoutParams = ViewGroup.LayoutParams(
10 ViewGroup.LayoutParams.MATCH_PARENT,
11 ViewGroup.LayoutParams.MATCH_PARENT
12 )
13 surface?.onScreenCreated = { screen ->
14 // Defines an action that should be done after the screen is created.
15 onScreenCreated(screen)
16 }
17 val params = FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, 400)
18 params.setMargins(50)
19 val frame = FrameLayout(requireContext())
20 frame.layoutParams = params
21 frame.addView(surface)
22 linearLayout.addView(frame)
23 }
24 private fun deleteLastSurface()
25 {
26 val linearLayout = view?.findViewById<LinearLayout>(R.id.scrolledLinearLayout) ?: return
27 if (linearLayout.childCount == 0)
28 return
29 val lastIndex = linearLayout.childCount - 1
30 val frame = (linearLayout[lastIndex] as FrameLayout)
31 val lastSurface = frame[0] as GemSurfaceView
32 SdkCall.execute
33 {
34 val mapsId = lastSurface.getScreen()?.address()
35 // Release the map view.
36 maps[mapsId]?.release()
37 // Remove the map view from the collection of displayed maps.
38 maps.remove(mapsId)
39 }
40 linearLayout.removeView(frame)
41 }
42 private fun onScreenCreated(screen: Screen)
43 {
44 SdkCall.checkCurrentThread() // Ensure we are on SDK thread.
45 /*
46 Define a rectangle in which the map view will expand.
47 Predefined value of the offsets is 0.
48 Value 1 means the offset will take 100% of available space.
49 */
50 val mainViewRect = RectF(0.0f, 0.0f, 1.0f, 1.0f)
51 // Produce a map view and establish that it is the main map view.
52 val mapView = MapView.produce(screen, mainViewRect) ?: return
53 // Add the map view to the collection of displayed maps.
54 maps[screen.address()] = mapView
55 }
56}
addSurface()
function calls onScreenCreated()
which adds a
map to the new surface, and also stores the map in a map container,
like a list, to enable removing it later:val mapView = MapView.produce(screen, mainViewRect)
maps[screen.address()] = mapView
deleteLastSurface()
function deletes the current map and removes
it from the map container/list.val mapsId = lastSurface.getScreen()?.address()
maps[mapsId]?.release()
maps.remove(mapsId)