diff --git a/ApiDemos/java/app/build.gradle b/ApiDemos/java/app/build.gradle
index 92c1814e..b01f8d40 100644
--- a/ApiDemos/java/app/build.gradle
+++ b/ApiDemos/java/app/build.gradle
@@ -26,4 +26,6 @@ dependencies {
implementation 'com.android.support:appcompat-v7:27.0.2'
implementation 'com.google.android.gms:play-services-maps:11.6.2'
implementation 'com.android.support:support-v4:27.0.2'
+ // Needed for the LiteListDemo
+ implementation "com.android.support:recyclerview-v7:27.0.2"
}
diff --git a/ApiDemos/java/app/src/main/java/com/example/mapdemo/LiteListDemoActivity.java b/ApiDemos/java/app/src/main/java/com/example/mapdemo/LiteListDemoActivity.java
index 563adfc0..8e5d901f 100755
--- a/ApiDemos/java/app/src/main/java/com/example/mapdemo/LiteListDemoActivity.java
+++ b/ApiDemos/java/app/src/main/java/com/example/mapdemo/LiteListDemoActivity.java
@@ -24,18 +24,18 @@ 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.support.v7.widget.GridLayoutManager;
+import android.support.v7.widget.LinearLayoutManager;
+import android.support.v7.widget.RecyclerView;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
-import android.widget.AbsListView;
-import android.widget.ArrayAdapter;
import android.widget.TextView;
-import java.util.HashSet;
-
/**
* This shows to include a map in lite mode in a ListView.
* Note the use of the view holder pattern with the
@@ -43,169 +43,171 @@ import java.util.HashSet;
*/
public class LiteListDemoActivity extends AppCompatActivity {
- private ListFragment mList;
+ private RecyclerView mRecyclerView;
- private MapAdapter mAdapter;
+ private LinearLayoutManager mLinearLayoutManager;
+ private GridLayoutManager mGridLayoutManager;
@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);
+ mGridLayoutManager = new GridLayoutManager(this, 2);
+ mLinearLayoutManager = new LinearLayoutManager(this);
- // Set a RecyclerListener to clean up MapView from ListView
- AbsListView lv = mList.getListView();
- lv.setRecyclerListener(mRecycleListener);
+ // Set up the RecyclerView
+ mRecyclerView = findViewById(R.id.recycler_view);
+ mRecyclerView.setHasFixedSize(true);
+ mRecyclerView.setLayoutManager(mLinearLayoutManager);
+ mRecyclerView.setAdapter(new MapAdapter(LIST_LOCATIONS));
+ mRecyclerView.setRecyclerListener(mRecycleListener);
+ }
+ /** Create a menu to switch between Linear and Grid LayoutManager. */
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ getMenuInflater().inflate(R.menu.lite_list_menu, menu);
+ return true;
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case R.id.layout_linear:
+ mRecyclerView.setLayoutManager(mLinearLayoutManager);
+ break;
+ case R.id.layout_grid:
+ mRecyclerView.setLayoutManager(mGridLayoutManager);
+ break;
+ }
+ return true;
}
/**
* Adapter that displays a title and {@link com.google.android.gms.maps.MapView} for each item.
* The layout is defined in lite_list_demo_row.xml. It contains a MapView
* that is programatically initialised in
- * {@link #getView(int, android.view.View, android.view.ViewGroup)}
+ * {@link #(int, android.view.View, android.view.ViewGroup)}
*/
- private class MapAdapter extends ArrayAdapter {
+ private class MapAdapter extends RecyclerView.Adapter {
- private final HashSet mMaps = new HashSet();
+ private NamedLocation[] namedLocations;
- public MapAdapter(Context context, NamedLocation[] locations) {
- super(context, R.layout.lite_list_demo_row, R.id.lite_listrow_text, locations);
+ private MapAdapter(NamedLocation[] locations) {
+ super();
+ namedLocations = 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;
+ public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+ return new ViewHolder(LayoutInflater.from(parent.getContext())
+ .inflate(R.layout.lite_list_demo_row, parent, false));
}
/**
- * Retuns the set of all initialised {@link MapView} objects.
- *
- * @return All MapViews that have been initialised programmatically by this adapter
+ * This function is called when the user scrolls through the screen and a new item needs
+ * to be shown. So we will need to bind the holder with the details of the next item.
*/
- public HashSet getMaps() {
- return mMaps;
+ @Override
+ public void onBindViewHolder(ViewHolder holder, int position) {
+ if (holder == null) {
+ return;
+ }
+ holder.bindView(position);
}
- }
-
- /**
- * Displays a {@link LiteListDemoActivity.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 LiteListDemoActivity.MapAdapter}.
- * Once the the map 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.
- */
- 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);
- }
+ public int getItemCount() {
+ return namedLocations.length;
}
/**
- * Initialises the MapView by calling its lifecycle methods.
+ * Holder for Views used in the {@link LiteListDemoActivity.MapAdapter}.
+ * Once the the map 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 void initializeMapView() {
- if (mapView != null) {
- // Initialise the MapView
- mapView.onCreate(null);
- // Set the map ready callback to receive the GoogleMap object
- mapView.getMapAsync(this);
+ class ViewHolder extends RecyclerView.ViewHolder implements OnMapReadyCallback {
+
+ MapView mapView;
+ TextView title;
+ GoogleMap map;
+ View layout;
+
+ private ViewHolder(View itemView) {
+ super(itemView);
+ layout = itemView;
+ mapView = layout.findViewById(R.id.lite_listrow_map);
+ title = layout.findViewById(R.id.lite_listrow_text);
+ if (mapView != null) {
+ // Initialise the MapView
+ mapView.onCreate(null);
+ // Set the map ready callback to receive the GoogleMap object
+ mapView.getMapAsync(this);
+ }
+ }
+
+ @Override
+ public void onMapReady(GoogleMap googleMap) {
+ MapsInitializer.initialize(getApplicationContext());
+ map = googleMap;
+ setMapLocation();
+ }
+
+ /**
+ * Displays a {@link LiteListDemoActivity.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 void setMapLocation() {
+ if (map == null) return;
+
+ NamedLocation data = (NamedLocation) mapView.getTag();
+ if (data == null) return;
+
+ // 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);
+ }
+
+ private void bindView(int pos) {
+ NamedLocation item = namedLocations[pos];
+ // Store a reference of the ViewHolder object in the layout.
+ layout.setTag(this);
+ // Store a reference to the item in the mapView's tag. We use it to get the
+ // coordinate of a location, when setting the map location.
+ mapView.setTag(item);
+ setMapLocation();
+ title.setText(item.name);
}
}
-
}
/**
* RecycleListener that completely clears the {@link com.google.android.gms.maps.GoogleMap}
- * attached to a row in the ListView.
+ * attached to a row in the RecyclerView.
* 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() {
+ private RecyclerView.RecyclerListener mRecycleListener = new RecyclerView.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);
+ public void onViewRecycled(RecyclerView.ViewHolder holder) {
+ MapAdapter.ViewHolder mapHolder = (MapAdapter.ViewHolder) holder;
+ if (mapHolder != null && mapHolder.map != null) {
+ // Clear the map and free up resources by changing the map type to none.
+ // Also reset the map when it gets reattached to layout, so the previous map would
+ // not be displayed.
+ mapHolder.map.clear();
+ mapHolder.map.setMapType(GoogleMap.MAP_TYPE_NONE);
}
-
}
};
@@ -216,7 +218,6 @@ public class LiteListDemoActivity extends AppCompatActivity {
private static class NamedLocation {
public final String name;
-
public final LatLng location;
NamedLocation(String name, LatLng location) {
diff --git a/ApiDemos/java/app/src/main/res/layout/lite_list_demo.xml b/ApiDemos/java/app/src/main/res/layout/lite_list_demo.xml
index 70c3742c..8b76eb6b 100755
--- a/ApiDemos/java/app/src/main/res/layout/lite_list_demo.xml
+++ b/ApiDemos/java/app/src/main/res/layout/lite_list_demo.xml
@@ -1,26 +1,22 @@
-
-
-
-
-
-
+ android:layout_height="match_parent" />
diff --git a/ApiDemos/java/app/src/main/res/layout/lite_list_demo_row.xml b/ApiDemos/java/app/src/main/res/layout/lite_list_demo_row.xml
index f6aef86a..4b3cda67 100755
--- a/ApiDemos/java/app/src/main/res/layout/lite_list_demo_row.xml
+++ b/ApiDemos/java/app/src/main/res/layout/lite_list_demo_row.xml
@@ -1,29 +1,30 @@
-
+
\ No newline at end of file
diff --git a/ApiDemos/java/app/src/main/res/values/strings.xml b/ApiDemos/java/app/src/main/res/values/strings.xml
index 8738cedb..f3ee393a 100755
--- a/ApiDemos/java/app/src/main/res/values/strings.xml
+++ b/ApiDemos/java/app/src/main/res/values/strings.xml
@@ -177,14 +177,16 @@
Mixed
+ Grid
Lite Mode
Demonstrates some features on a map in lite mode.
Click the map with no, one or multiple markers displayed to open the Google Maps Mobile app.
Go to Darwin (No Markers)
Go to Adelaide (One Marker)
Go to Australia (Five Markers)
- Lite Mode ListView
- Demonstrates using maps in lite mode in a ListView.
+ Linear
+ Lite Mode List
+ Demonstrates using maps in lite mode in a RecyclerView using LinearLayoutManager and GridLayoutManager.
Activate Higher Level
diff --git a/ApiDemos/java/gradle/wrapper/gradle-wrapper.properties b/ApiDemos/java/gradle/wrapper/gradle-wrapper.properties
index e947089b..6f775bb9 100644
--- a/ApiDemos/java/gradle/wrapper/gradle-wrapper.properties
+++ b/ApiDemos/java/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
-#Tue Jun 06 10:13:43 AEST 2017
+#Thu Jan 18 10:58:29 AEDT 2018
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip