Java tutorial
/* * Copyright (C) 2014 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package medis.ourlab.labkita.activity; import com.google.android.gms.maps.CameraUpdateFactory; import com.google.android.gms.maps.GoogleMap; import com.google.android.gms.maps.MapView; import com.google.android.gms.maps.MapsInitializer; import com.google.android.gms.maps.OnMapReadyCallback; import com.google.android.gms.maps.model.LatLng; import com.google.android.gms.maps.model.MarkerOptions; import android.content.Context; import android.os.Bundle; import android.support.v4.app.ListFragment; import android.support.v7.app.AppCompatActivity; import android.view.View; import android.view.ViewGroup; import android.widget.AbsListView; import android.widget.ArrayAdapter; import android.widget.TextView; import java.util.HashSet; import medis.ourlab.labkita.R; /** * This shows to include a map in lite mode in a ListView. * Note the use of the view holder pattern with the * {@link com.google.android.gms.maps.OnMapReadyCallback}. */ public class LiteListDemo extends AppCompatActivity { private ListFragment mList; private MapAdapter mAdapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.lite_list_demo); // Set a custom list adapter for a list of locations mAdapter = new MapAdapter(this, LIST_LOCATIONS); mList = (ListFragment) getSupportFragmentManager().findFragmentById(R.id.list); mList.setListAdapter(mAdapter); // Set a RecyclerListener to clean up MapView from ListView AbsListView lv = mList.getListView(); lv.setRecyclerListener(mRecycleListener); } /** * Adapter that displays a title and {@link com.google.android.gms.maps.MapView} for each item. * The layout is defined in <code>lite_list_demo_row.xml</code>. It contains a MapView * that is programatically initialised in * {@link #getView(int, android.view.View, android.view.ViewGroup)} */ private class MapAdapter extends ArrayAdapter<NamedLocation> { private final HashSet<MapView> mMaps = new HashSet<MapView>(); public MapAdapter(Context context, NamedLocation[] locations) { super(context, R.layout.lite_list_demo_row, R.id.lite_listrow_text, locations); } @Override public View getView(int position, View convertView, ViewGroup parent) { View row = convertView; ViewHolder holder; // Check if a view can be reused, otherwise inflate a layout and set up the view holder if (row == null) { // Inflate view from layout file row = getLayoutInflater().inflate(R.layout.lite_list_demo_row, null); // Set up holder and assign it to the View holder = new ViewHolder(); holder.mapView = (MapView) row.findViewById(R.id.lite_listrow_map); holder.title = (TextView) row.findViewById(R.id.lite_listrow_text); // Set holder as tag for row for more efficient access. row.setTag(holder); // Initialise the MapView holder.initializeMapView(); // Keep track of MapView mMaps.add(holder.mapView); } else { // View has already been initialised, get its holder holder = (ViewHolder) row.getTag(); } // Get the NamedLocation for this item and attach it to the MapView NamedLocation item = getItem(position); holder.mapView.setTag(item); // Ensure the map has been initialised by the on map ready callback in ViewHolder. // If it is not ready yet, it will be initialised with the NamedLocation set as its tag // when the callback is received. if (holder.map != null) { // The map is already ready to be used setMapLocation(holder.map, item); } // Set the text label for this item holder.title.setText(item.name); return row; } /** * Retuns the set of all initialised {@link MapView} objects. * * @return All MapViews that have been initialised programmatically by this adapter */ public HashSet<MapView> getMaps() { return mMaps; } } /** * Displays a {@link LiteListDemo.NamedLocation} on a * {@link com.google.android.gms.maps.GoogleMap}. * Adds a marker and centers the camera on the NamedLocation with the normal map type. */ private static void setMapLocation(GoogleMap map, NamedLocation data) { // Add a marker for this item and set the camera map.moveCamera(CameraUpdateFactory.newLatLngZoom(data.location, 13f)); map.addMarker(new MarkerOptions().position(data.location)); // Set the map type back to normal. map.setMapType(GoogleMap.MAP_TYPE_NORMAL); } /** * Holder for Views used in the {@link LiteListDemo.MapAdapter}. * Once the the <code>map</code> field is set, otherwise it is null. * When the {@link #onMapReady(com.google.android.gms.maps.GoogleMap)} callback is received and * the {@link com.google.android.gms.maps.GoogleMap} is ready, it stored in the {@link #map} * field. The map is then initialised with the NamedLocation that is stored as the tag of the * MapView. This ensures that the map is initialised with the latest data that it should * display. */ public class ViewHolder implements OnMapReadyCallback { MapView mapView; TextView title; GoogleMap map; @Override public void onMapReady(GoogleMap googleMap) { MapsInitializer.initialize(getApplicationContext()); map = googleMap; NamedLocation data = (NamedLocation) mapView.getTag(); if (data != null) { setMapLocation(map, data); } } /** * Initialises the MapView by calling its lifecycle methods. */ public void initializeMapView() { if (mapView != null) { // Initialise the MapView mapView.onCreate(null); // Set the map ready callback to receive the GoogleMap object mapView.getMapAsync(this); } } } /** * RecycleListener that completely clears the {@link com.google.android.gms.maps.GoogleMap} * attached to a row in the ListView. * Sets the map type to {@link com.google.android.gms.maps.GoogleMap#MAP_TYPE_NONE} and clears * the map. */ private AbsListView.RecyclerListener mRecycleListener = new AbsListView.RecyclerListener() { @Override public void onMovedToScrapHeap(View view) { ViewHolder holder = (ViewHolder) view.getTag(); if (holder != null && holder.map != null) { // Clear the map and free up resources by changing the map type to none holder.map.clear(); holder.map.setMapType(GoogleMap.MAP_TYPE_NONE); } } }; /** * Location represented by a position ({@link com.google.android.gms.maps.model.LatLng} and a * name ({@link java.lang.String}). */ private static class NamedLocation { public final String name; public final LatLng location; NamedLocation(String name, LatLng location) { this.name = name; this.location = location; } } /** * A list of locations to show in this ListView. */ private static final NamedLocation[] LIST_LOCATIONS = new NamedLocation[] { new NamedLocation("Cape Town", new LatLng(-33.920455, 18.466941)), new NamedLocation("Beijing", new LatLng(39.937795, 116.387224)), new NamedLocation("Bern", new LatLng(46.948020, 7.448206)), new NamedLocation("Breda", new LatLng(51.589256, 4.774396)), new NamedLocation("Brussels", new LatLng(50.854509, 4.376678)), new NamedLocation("Copenhagen", new LatLng(55.679423, 12.577114)), new NamedLocation("Hannover", new LatLng(52.372026, 9.735672)), new NamedLocation("Helsinki", new LatLng(60.169653, 24.939480)), new NamedLocation("Hong Kong", new LatLng(22.325862, 114.165532)), new NamedLocation("Istanbul", new LatLng(41.034435, 28.977556)), new NamedLocation("Johannesburg", new LatLng(-26.202886, 28.039753)), new NamedLocation("Lisbon", new LatLng(38.707163, -9.135517)), new NamedLocation("London", new LatLng(51.500208, -0.126729)), new NamedLocation("Madrid", new LatLng(40.420006, -3.709924)), new NamedLocation("Mexico City", new LatLng(19.427050, -99.127571)), new NamedLocation("Moscow", new LatLng(55.750449, 37.621136)), new NamedLocation("New York", new LatLng(40.750580, -73.993584)), new NamedLocation("Oslo", new LatLng(59.910761, 10.749092)), new NamedLocation("Paris", new LatLng(48.859972, 2.340260)), new NamedLocation("Prague", new LatLng(50.087811, 14.420460)), new NamedLocation("Rio de Janeiro", new LatLng(-22.90187, -43.232437)), new NamedLocation("Rome", new LatLng(41.889998, 12.500162)), new NamedLocation("Sao Paolo", new LatLng(-22.863878, -43.244097)), new NamedLocation("Seoul", new LatLng(37.560908, 126.987705)), new NamedLocation("Stockholm", new LatLng(59.330650, 18.067360)), new NamedLocation("Sydney", new LatLng(-33.873651, 151.2068896)), new NamedLocation("Taipei", new LatLng(25.022112, 121.478019)), new NamedLocation("Tokyo", new LatLng(35.670267, 139.769955)), new NamedLocation("Tulsa Oklahoma", new LatLng(36.149777, -95.993398)), new NamedLocation("Vaduz", new LatLng(47.141076, 9.521482)), new NamedLocation("Vienna", new LatLng(48.209206, 16.372778)), new NamedLocation("Warsaw", new LatLng(52.235474, 21.004057)), new NamedLocation("Wellington", new LatLng(-41.286480, 174.776217)), new NamedLocation("Winnipeg", new LatLng(49.875832, -97.150726)) }; }