summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTobrun Van Nuland <tobrun.van.nuland@gmail.com>2016-08-24 13:31:20 +0200
committerTobrun Van Nuland <tobrun.van.nuland@gmail.com>2016-08-24 13:31:20 +0200
commit7adf0c6a74a3521d60453bd0c6a0a73b95956d82 (patch)
treeebec064c6160be82c67e05ef538febfd0ae18a35
parent9720f581ff614f625819c31ea6f26f61b930342b (diff)
downloadqtlocation-mapboxgl-upstream/5238-ViewAnnotationsZordering.tar.gz
[android] #5238 - Add ordering based on adapter, each adapter has its own frame layoutupstream/5238-ViewAnnotationsZordering
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerViewManager.java23
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapView.java26
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/AndroidManifest.xml9
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/MarkerViewZOrderingActivity.java254
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_marker_view_z.xml24
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/view_rectangle.xml5
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/strings.xml2
7 files changed, 337 insertions, 6 deletions
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerViewManager.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerViewManager.java
index 9631bc4ca8..8ad45c6fec 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerViewManager.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerViewManager.java
@@ -9,6 +9,7 @@ import android.support.annotation.Nullable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
+import android.widget.FrameLayout;
import android.widget.ImageView;
import com.mapbox.mapboxsdk.R;
@@ -316,12 +317,32 @@ public class MarkerViewManager {
* @param markerViewAdapter the MarkerViewAdapter to add
*/
public void addMarkerViewAdapter(MapboxMap.MarkerViewAdapter markerViewAdapter) {
+ addMarkerViewAdapter(markerViewAdapter, 0);
+ }
+
+
+ /**
+ * Add a MarkerViewAdapter to the MarkerViewManager.
+ * <p>
+ * The provided MarkerViewAdapter must use supply a generic subclass of MarkerView.
+ * </p>
+ *
+ * @param markerViewAdapter the MarkerViewAdapter to add
+ */
+ public void addMarkerViewAdapter(MapboxMap.MarkerViewAdapter markerViewAdapter, int index) {
if (markerViewAdapter.getMarkerClass().equals(MarkerView.class)) {
throw new RuntimeException("Providing a custom MarkerViewAdapter requires subclassing MarkerView");
}
if (!markerViewAdapters.contains(markerViewAdapter)) {
+
+ // add container
+ mapView.addMarkerViewContainer(markerViewAdapter.getMarkerClass(), index);
+
+ // add to adapter list
markerViewAdapters.add(markerViewAdapter);
+
+ // invalidate adapters
invalidateViewMarkersInVisibleRegion();
}
}
@@ -438,7 +459,7 @@ public class MarkerViewManager {
markerViewMap.put(marker, adaptedView);
if (convertView == null) {
adaptedView.setVisibility(View.GONE);
- mapView.getMarkerViewContainer().addView(adaptedView);
+ mapView.getMarkerViewContainer(adapter.getMarkerClass()).addView(adaptedView);
}
}
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapView.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapView.java
index 3cb28ed395..5d8d0bbb84 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapView.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapView.java
@@ -32,6 +32,7 @@ import android.support.annotation.UiThread;
import android.support.v4.content.ContextCompat;
import android.support.v4.view.GestureDetectorCompat;
import android.support.v4.view.ScaleGestureDetectorCompat;
+import android.support.v4.view.ViewPager;
import android.support.v7.app.AlertDialog;
import android.text.TextUtils;
import android.util.AttributeSet;
@@ -123,7 +124,8 @@ public class MapView extends FrameLayout {
private NativeMapView mNativeMapView;
private boolean mHasSurface = false;
- private ViewGroup mMarkerViewContainer;
+ private ViewGroup mMarkerViewParentContainer;
+ private List<ViewGroup> mMarkerViewContainers;
private CompassView mCompassView;
private ImageView mLogoView;
private ImageView mAttributionsView;
@@ -227,7 +229,8 @@ public class MapView extends FrameLayout {
// Connectivity
onConnectivityChanged(isConnected());
- mMarkerViewContainer = (ViewGroup) view.findViewById(R.id.markerViewContainer);
+ mMarkerViewParentContainer = (ViewGroup) view.findViewById(R.id.markerViewContainer);
+ mMarkerViewContainers = new ArrayList<>();
mMyLocationView = (MyLocationView) view.findViewById(R.id.userLocationView);
mMyLocationView.setMapboxMap(mMapboxMap);
@@ -1203,8 +1206,21 @@ public class MapView extends FrameLayout {
/**
* @return the ViewGroup containing the marker views
*/
- public ViewGroup getMarkerViewContainer() {
- return mMarkerViewContainer;
+ public ViewGroup getMarkerViewContainer(Class markerViewClass) {
+ for (ViewGroup container : mMarkerViewContainers) {
+ if ((container.getTag().equals(markerViewClass))) {
+ return container;
+ }
+ }
+ throw new IllegalStateException("Container should be availlable for "+markerViewClass.toString());
+ }
+
+ public void addMarkerViewContainer(Class markerClass, int index){
+ FrameLayout markerViewContainer = new FrameLayout(getContext());
+ markerViewContainer.setLayoutParams(new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
+ markerViewContainer.setTag(markerClass);
+ mMarkerViewParentContainer.addView(markerViewContainer, index);
+ mMarkerViewContainers.add(markerViewContainer);
}
@@ -1729,7 +1745,7 @@ public class MapView extends FrameLayout {
(tapPoint.y - mAverageIconHeight / 2 - toleranceTopBottom) / mScreenDensity,
(tapPoint.x + mAverageIconWidth / 2 + toleranceSides) / mScreenDensity,
(tapPoint.y + mAverageIconHeight / 2 + toleranceTopBottom) / mScreenDensity);
-
+
List<Marker> nearbyMarkers = getMarkersInRect(tapRect);
long newSelectedMarkerId = -1;
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/AndroidManifest.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/AndroidManifest.xml
index d582719af6..07e4ca143a 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/AndroidManifest.xml
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/AndroidManifest.xml
@@ -367,6 +367,15 @@
android:name="@string/category"
android:value="@string/category_navigation" />
</activity>
+ <activity
+ android:name=".activity.annotation.MarkerViewZOrderingActivity"
+ android:description="@string/description_marker_view_z_ordering"
+ android:label="@string/activity_view_marker_z_ordering">
+ <meta-data
+ android:name="@string/category"
+ android:value="@string/category_annotation" />
+
+ </activity>
<!-- For Unit tests -->
<activity android:name=".activity.style.RuntimeStyleTestActivity" />
<activity android:name=".activity.style.RuntimeStyleTimingTestActivity" />
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/MarkerViewZOrderingActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/MarkerViewZOrderingActivity.java
new file mode 100644
index 0000000000..68cf05e269
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/MarkerViewZOrderingActivity.java
@@ -0,0 +1,254 @@
+package com.mapbox.mapboxsdk.testapp.activity.annotation;
+
+import android.animation.Animator;
+import android.animation.AnimatorInflater;
+import android.animation.AnimatorListenerAdapter;
+import android.content.Context;
+import android.os.Bundle;
+import android.os.PersistableBundle;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.support.v7.app.ActionBar;
+import android.support.v7.app.AppCompatActivity;
+import android.support.v7.widget.Toolbar;
+import android.view.LayoutInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.TextView;
+
+import com.mapbox.mapboxsdk.annotations.BaseMarkerViewOptions;
+import com.mapbox.mapboxsdk.annotations.MarkerView;
+import com.mapbox.mapboxsdk.annotations.MarkerViewManager;
+import com.mapbox.mapboxsdk.camera.CameraPosition;
+import com.mapbox.mapboxsdk.geometry.LatLng;
+import com.mapbox.mapboxsdk.maps.MapView;
+import com.mapbox.mapboxsdk.maps.MapboxMap;
+import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
+import com.mapbox.mapboxsdk.testapp.R;
+import com.mapbox.mapboxsdk.testapp.model.annotations.PulseMarkerView;
+import com.mapbox.mapboxsdk.testapp.model.annotations.PulseMarkerViewOptions;
+import com.mapbox.mapboxsdk.testapp.model.annotations.TextMarkerView;
+import com.mapbox.mapboxsdk.testapp.model.annotations.TextMarkerViewOptions;
+
+import java.util.ArrayList;
+
+public class MarkerViewZOrderingActivity extends AppCompatActivity {
+
+ private static final String KEY_PARCEABLE_MARKERVIEWOPTIONS = "com.mapbox.markerviewoptions";
+
+ private MapView mapView;
+ private ArrayList<BaseMarkerViewOptions> markerViewOptions;
+
+ @Override
+ protected void onCreate(final Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_marker_view_z);
+
+ Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
+ setSupportActionBar(toolbar);
+
+ ActionBar actionBar = getSupportActionBar();
+ if (actionBar != null) {
+ actionBar.setDisplayHomeAsUpEnabled(true);
+ actionBar.setDisplayShowHomeEnabled(true);
+ }
+
+ mapView = (MapView) findViewById(R.id.mapView);
+ mapView.onCreate(savedInstanceState);
+ mapView.getMapAsync(new OnMapReadyCallback() {
+ @Override
+ public void onMapReady(MapboxMap mapboxMap) {
+
+ // add marker view adapter
+ MarkerViewManager markerViewManager = mapboxMap.getMarkerViewManager();
+ markerViewManager.addMarkerViewAdapter(new BackgroundViewAdapter(MarkerViewZOrderingActivity.this), 0 /* Index in parent layout */);
+ markerViewManager.addMarkerViewAdapter(new TextAdapter(MarkerViewZOrderingActivity.this, mapboxMap), 1 /* I'm added in front of above */);
+
+ if (savedInstanceState == null) {
+ markerViewOptions = new ArrayList<>();
+
+ TextMarkerViewOptions diplomaticRoomOptions = new TextMarkerViewOptions().position(new LatLng(38.897605, -77.036580)).text("Diplomatic Room");
+ MarkerView diplomaticRoom = mapboxMap.addMarker(diplomaticRoomOptions);
+ markerViewOptions.add(diplomaticRoomOptions);
+
+ TextMarkerViewOptions kitchenOptions = new TextMarkerViewOptions().position(new LatLng(38.897745, -77.036784)).text("Kitchen");
+ mapboxMap.addMarker(kitchenOptions);
+ markerViewOptions.add(kitchenOptions);
+
+ TextMarkerViewOptions library = new TextMarkerViewOptions().position(new LatLng(38.897751, -77.036407)).text("Library");
+ mapboxMap.addMarker(library);
+ markerViewOptions.add(library);
+
+ PulseMarkerViewOptions background = new PulseMarkerViewOptions().position(new LatLng(38.897654, -77.036589)).anchor(0.5f, 0.5f).alpha(0.33f);
+ PulseMarkerView markerView = (PulseMarkerView) mapboxMap.addMarker(background);
+ markerView.setAlpha(0.33f);
+ markerView.setAnchor(0.5f, 0.5f);
+ markerViewOptions.add(background);
+
+ } else {
+ // restore markers
+ markerViewOptions = savedInstanceState.getParcelableArrayList(KEY_PARCEABLE_MARKERVIEWOPTIONS);
+ if (markerViewOptions != null) {
+ for (BaseMarkerViewOptions textMarkerViewOptions : markerViewOptions) {
+ mapboxMap.addMarker(textMarkerViewOptions);
+ }
+ }
+ }
+ }
+ });
+ }
+
+ private static class BackgroundViewAdapter extends MapboxMap.MarkerViewAdapter<PulseMarkerView> {
+
+ private LayoutInflater inflater;
+
+ public BackgroundViewAdapter(@NonNull Context context) {
+ super(context);
+ this.inflater = LayoutInflater.from(context);
+ }
+
+ @Nullable
+ @Override
+ public View getView(@NonNull PulseMarkerView marker, @Nullable View convertView, @NonNull ViewGroup parent) {
+ return inflater.inflate(R.layout.view_rectangle, parent, false);
+ }
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ mapView.onResume();
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ mapView.onPause();
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ mapView.onDestroy();
+ }
+
+ @Override
+ public void onSaveInstanceState(Bundle outState, PersistableBundle outPersistentState) {
+ super.onSaveInstanceState(outState, outPersistentState);
+ mapView.onSaveInstanceState(outState);
+ outState.putParcelableArrayList(KEY_PARCEABLE_MARKERVIEWOPTIONS, markerViewOptions);
+ }
+
+ @Override
+ public void onLowMemory() {
+ super.onLowMemory();
+ mapView.onLowMemory();
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case android.R.id.home:
+ onBackPressed();
+ return true;
+ default:
+ return super.onOptionsItemSelected(item);
+ }
+ }
+
+ private static class TextAdapter extends MapboxMap.MarkerViewAdapter<TextMarkerView> {
+
+ private LayoutInflater inflater;
+ private MapboxMap mapboxMap;
+
+ public TextAdapter(@NonNull Context context, @NonNull MapboxMap mapboxMap) {
+ super(context);
+ this.inflater = LayoutInflater.from(context);
+ this.mapboxMap = mapboxMap;
+ }
+
+ @Nullable
+ @Override
+ public View getView(@NonNull TextMarkerView marker, @Nullable View convertView, @NonNull ViewGroup parent) {
+ ViewHolder viewHolder;
+ if (convertView == null) {
+ viewHolder = new ViewHolder();
+ convertView = inflater.inflate(R.layout.view_text_marker, parent, false);
+ viewHolder.textView = (TextView) convertView.findViewById(R.id.textView);
+ convertView.setTag(viewHolder);
+ } else {
+ viewHolder = (ViewHolder) convertView.getTag();
+ }
+ viewHolder.textView.setText(marker.getText());
+ return convertView;
+ }
+
+ @Override
+ public boolean onSelect(@NonNull final TextMarkerView marker, @NonNull final View convertView, boolean reselectionForViewReuse) {
+ animateGrow(marker, convertView, 0);
+
+ // false indicates that we are calling selectMarker after our animation ourselves
+ // true will let the system call it for you, which will result in showing an InfoWindow instantly
+ return false;
+ }
+
+ @Override
+ public void onDeselect(@NonNull TextMarkerView marker, @NonNull final View convertView) {
+ animateShrink(convertView, 350);
+ }
+
+ @Override
+ public boolean prepareViewForReuse(@NonNull MarkerView marker, @NonNull View convertView) {
+ // this method is called before a view will be reused, we need to restore view state
+ // as we have scaled the view in onSelect. If not correctly applied other MarkerView will
+ // become large since these have been recycled
+
+ // cancel ongoing animation
+ convertView.animate().cancel();
+
+ if (marker.isSelected()) {
+ // shrink view to be able to be reused
+ animateShrink(convertView, 0);
+ }
+
+ // true if you want reuse to occur automatically, false if you want to manage this yourself
+ return true;
+ }
+
+ private void animateGrow(@NonNull final MarkerView marker, @NonNull final View convertView, int duration) {
+ convertView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
+ Animator animator = AnimatorInflater.loadAnimator(convertView.getContext(), R.animator.scale_up);
+ animator.setDuration(duration);
+ animator.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ super.onAnimationEnd(animation);
+ convertView.setLayerType(View.LAYER_TYPE_NONE, null);
+ mapboxMap.selectMarker(marker);
+ }
+ });
+ animator.setTarget(convertView);
+ animator.start();
+ }
+
+ private void animateShrink(@NonNull final View convertView, int duration) {
+ convertView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
+ Animator animator = AnimatorInflater.loadAnimator(convertView.getContext(), R.animator.scale_down);
+ animator.setDuration(duration);
+ animator.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ super.onAnimationEnd(animation);
+ convertView.setLayerType(View.LAYER_TYPE_NONE, null);
+ }
+ });
+ animator.setTarget(convertView);
+ animator.start();
+ }
+
+ private static class ViewHolder {
+ TextView textView;
+ }
+ }
+}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_marker_view_z.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_marker_view_z.xml
new file mode 100644
index 0000000000..993d790a83
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_marker_view_z.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <android.support.v7.widget.Toolbar
+ android:id="@id/toolbar"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:background="@color/primary"
+ android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" />
+
+ <com.mapbox.mapboxsdk.maps.MapView
+ android:id="@id/mapView"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_below="@id/toolbar"
+ app:center_latitude="38.897686"
+ app:center_longitude="-77.036589"
+ app:style_url="@string/style_mapbox_streets"
+ app:zoom="18" />
+
+</RelativeLayout> \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/view_rectangle.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/view_rectangle.xml
new file mode 100644
index 0000000000..763d65948a
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/view_rectangle.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="512dp"
+ android:layout_height="512dp"
+ android:background="@color/mapbox_blue" /> \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/strings.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/strings.xml
index d8f2edd85e..d6f7cd6313 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/strings.xml
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/strings.xml
@@ -19,6 +19,7 @@
<string name="activity_press_for_marker">Press Map For Marker</string>
<string name="activity_view_marker">View Marker API</string>
<string name="activity_view_marker_scale">Scaling in the View Marker API</string>
+ <string name="activity_view_marker_z_ordering">View Marker Z ordering</string>
<!-- InfoWindow-->
<string name="activity_info_window">Standard InfoWindow</string>
@@ -108,6 +109,7 @@
<string name="description_query_rendered_features_box_count">Count all rendered features in box</string>
<string name="description_query_rendered_features_box_highlight">Hightligh buildings in box</string>
<string name="description_car_driving">MyLocationView follow map update example</string>
+ <string name="description_marker_view_z_ordering">Marker View Z ordering</string>
<string name="menuitem_title_concurrent_infowindow">Concurrent Open InfoWindows</string>
<string name="menuitem_title_deselect_markers_on_tap">Deselect Markers On Tap</string>