Getting Started With Google Maps for Android: Intermediate

Introduction

One of the most useful features for users is maps integration. In the previous installment of this series, we discussed how to set up Google Maps for Android using the Google Developer Console and how to create a basic Google Maps fragment. We then went over adding different kinds of markers and how to draw on the map.

In this tutorial, you will expand on what you learned in the last article in order to lay views on top of a map, override the indoor level selector controls, and add a Street View component to your applications. The source code for this article can be found on GitHub.

1. Getting Set Up

To start, follow the steps listed in the previous article of this series in order to create a basic project using a MapFragment, attach it to an Activity, and activate the Google Maps API through the Google Developers Console. For this tutorial, you don't need to use the locations Play Services classes, but you do need to import maps Play Services library into your build.gradle dependencies node.

Once that's done, you end up with a screen that looks like the following:

Initial map view

Next, you need to set up your camera. For this tutorial, we will focus on Madison Square Garden in New York City, because it's a great example of a building using the indoor level maps.

In onViewCreated, you can add a call to the the following helper method initCamera. You may remember that we need to wait until onViewCreated to work with Google Maps, because this is when we know the map object is ready for use.

The above method moves the camera to our target and zooms in close enough that the indoor selector becomes visible. You'll notice that there's a strip of numbers on the right side of the screen and an overlay on the map for each floor. When you select a different level on the right, the current floor plan animates into the new one. This is the feature that you will work with later in order to have your own view control level selection.

Example of the default indoor level selector

Next, you need to implement the three interfaces that will be used in this tutorial.

  • GoogleMap.OnIndoorStateChangeListener is used for determining when an indoor level selector has changed visibility.
  • SeekBar.OnSeekBarChangeListener is used with one of our view overlays to control level selection, rather than using the default set of buttons on the right.
  • GoogleMap.OnMapLongClickListener is used in this example for changing the displayed location of your Street View component.

Once you have added the required methods for those three interfaces, you can begin adding views on top of the map.

2. Overlaying Views

While the base features of Google Maps fit most needs, there will be times that you want to add additional views over the map in order to perform actions. For this tutorial, we will add a SeekBar and some TextView objects in order to customize the controls for the indoor level selector.

Start by creating a new XML layout file, view_map_overlay.xml. Add the following code to create the base layout that will be used on the screen.

Once your layout file is complete, you can add it as an overlay to your maps fragment. In onCreateView, you need to access the ViewGroup parent, inflate your new layout overlay, and attach it to the parent. This is also where you save references to each of the views in your overlay so that they can be changed later in your app.

When you run the application, you should see your views on top of the map. You will, however, also still see the default level selector, which clutters up the view.

Overlay before the default indoor level selector controls are removed

In order to fix this, create a new method named initMapIndoorSelector and call it from onViewCreated. All it needs to do, is set your listeners for the SeekBar and indoor level changes, as well as disable the default indoor level picker.

Now that you have your view overlaying the map, you have to hide it until it's needed. In onViewCreated, call a new helper method named hideFloorLevelSelector that hides all of your overlaid views.

3. Using the Indoor Level Selector

With your views created and hidden, you can start adding in the logic to make your views appear when needed and interact with the map. Earlier, you created the onIndoorBuildingFocused method as a part of the GoogleMap.OnIndoorStateChangeListener. In that method, you need to save a reference to whichever building is in focus and then hide or show the SeekBar controls when necessary.

An indoor building will gain focus when the building is visible to the map camera and the map is zoomed in enough. If those conditions are no longer met, this method will be called again and getMap().getFocusedBuilding will return a null value.

showFloorLevelSelector makes all of the overlaid views visible, moves the SeekBar to the proper selected value, and sets the text labels to values representing the short name of the top and bottom floors for that building. When you retrieve the levels from an IndoorBuilding object, the bottom floor is the last item in the list and the top floor is at position 0.

The final method you need to implement for your indoor level selector is onProgressChanged(SeekBar seekBar, int progress, boolean fromUser). When the SeekBar position is changed, you need to activate a new level on the current building. Since the levels are ordered from top to bottom, you need to activate the level at position numOfLevels - 1 - progress in order to correlate with the position of the SeekBar.

4. Adding Street View

Now that you know how to overlay views on your a map and how to work with the indoor level selector, let's jump into how to work with Street View in your apps. Just like Google Maps, Street View allows you to either use a fragment or a view. For this example, you will use a StreetViewPanoramaView and overlay it onto your MapFragment.

This view will be initialized to show the street next to Madison Square Garden and when you long-press on a different area of the map, Street View will display images associated with the selected position. If you select to display an area that isn't directly connected to a Street View image, Google will pick the nearest to display if it's within a set distance. If no Street View images are nearby (say you select a location in the middle of the ocean), then Street View will show a black screen.

Something else to be aware of is that you can only have one StreetViewPanoramaView or fragment visible to the user at a time.

Street View on Madison Square Garden

To start, update view_map_overlay.xml in order to add a StreetViewPanoramaView.

When your layout file is ready, go into onCreateView in your MapFragment, save a reference to your new view, and call the onCreate method for the view. It's important that you call onCreate, because the current fragment's onCreate has already been called before this view was attached, and the Street View component performs actions in onCreate that are necessary for initialization.

Next, in onViewCreated, add a new method called initStreetView. This new method will asynchronously get the StreetViewPanorama object when it's ready and handle showing your initial Street View position. It's important to note that getStreetViewPanoramaAsync( OnStreetViewPanoramaReadyCallback callback ) can only be called from the main thread.

Finally, you need to define the showStreetView( LatLng latlng ) helper method shown above. This method creates a StreetViewPanoramaCamera object that allows you to change the tilt, zoom, and bearing of the Street View camera. For this example, the camera is set to the default values.

Next, you need to set the camera position. In this example, we also turn on an optional setting to show street names.

Once your showStreetView( LatLng latlng ) method is complete, it can also be called from onMapLongClick(LatLng latLng) so you can easily change what area is being shown.

Street View location changed by onMapLongClickLatLng latLng

Conclusion

In this tutorial, you learned about some advanced ways you can interact with Google Maps by adding additional views to the MapFragment and you learned how to control the indoor building level selector. We also covered the basics of adding Street View functionality to your application in order to display a different point of view for your users.

In the next installment of this series, you will learn about the Google Maps Utilities library and how to use it to add marker clusters, heat maps, and other useful features for your applications.

Tags:

Comments

Related Articles