package com.mapbox.mapboxsdk.annotations; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.AnimatorSet; import android.animation.ObjectAnimator; import android.content.Context; import android.graphics.PointF; import android.os.CountDownTimer; import android.os.SystemClock; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.animation.AnimationUtils; import android.widget.ImageView; import com.mapbox.mapboxsdk.R; import com.mapbox.mapboxsdk.maps.MapView; import com.mapbox.mapboxsdk.maps.MapboxMap; import com.mapbox.mapboxsdk.maps.Projection; import com.mapbox.mapboxsdk.utils.AnimatorUtils; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; /** * Interface for interacting with ViewMarkers objects inside of a MapView. *
* This class is responsible for managing a {@link MarkerView} item. *
*/ public class MarkerViewManager { private Map* The {@link MarkerView} will be rotated from its current rotation to the given rotation. *
* * @param marker the MarkerView to rotate * @param rotation the rotation value */ public void animateRotation(@NonNull MarkerView marker, float rotation) { View convertView = markerViewMap.get(marker); if (convertView != null) { AnimatorUtils.rotate(convertView, rotation); } } /** * Animate a MarkerView to a given alpha value. ** The {@link MarkerView} will be transformed from its current alpha value to the given value. *
* * @param marker the MarkerView to change its alpha value * @param alpha the alpha value */ public void animateAlpha(@NonNull MarkerView marker, float alpha) { View convertView = markerViewMap.get(marker); if (convertView != null) { AnimatorUtils.alpha(convertView, alpha); } } /** * Animate a MarkerVIew to be visible or invisible ** The {@link MarkerView} will be made {@link View#VISIBLE} or {@link View#GONE}. *
* * @param marker the MarkerView to change its visibility * @param visible the flag indicating if MarkerView is visible */ public void animateVisible(@NonNull MarkerView marker, boolean visible) { View convertView = markerViewMap.get(marker); if (convertView != null) { convertView.setVisibility(visible ? View.VISIBLE : View.GONE); } } /** * Updates the position of MarkerViews currently found in the viewport. ** The collection of {@link MarkerView} will be iterated and each item position will be updated. * If an item is View state is not visible and its related flag is set to visible, * The {@link MarkerView} will be animated to visible using alpha animation. *
*/ public void update() { for (final MarkerView marker : markerViewMap.keySet()) { final View convertView = markerViewMap.get(marker); if (convertView != null) { if (marker.isAnimating() || !marker.shouldAnimate()) { if (marker.isAnimating()) { // cancel ongoing animations marker.setAnimating(false); AnimatorSet set = marker.getAnimation(); List* The {@link com.mapbox.mapboxsdk.maps.MapboxMap.MarkerViewAdapter#onDeselect(MarkerView, View)} will be called to execute an animation. *
* * @param marker the MarkerView to deselect */ public void deselect(@NonNull MarkerView marker) { final View convertView = markerViewMap.get(marker); if (convertView != null) { for (MapboxMap.MarkerViewAdapter adapter : markerViewAdapters) { if (adapter.getMarkerClass().equals(marker.getClass())) { adapter.onDeselect(marker, convertView); } } } } /** * Animate a MarkerView to a selected state. * * @param marker the MarkerView object to select */ public void select(@NonNull MarkerView marker) { final View convertView = markerViewMap.get(marker); for (MapboxMap.MarkerViewAdapter adapter : markerViewAdapters) { if (adapter.getMarkerClass().equals(marker.getClass())) { select(marker, convertView, adapter); } } } /** * Animate a MarkerView to a selected state. ** The {@link com.mapbox.mapboxsdk.maps.MapboxMap.MarkerViewAdapter#onSelect(MarkerView, View, boolean)} will be called to execute an animation. *
* * @param marker the MarkerView object to select * @param convertView the View presentation of the MarkerView * @param adapter the adapter used to adapt the marker to the convertView */ public void select(@NonNull MarkerView marker, View convertView, MapboxMap.MarkerViewAdapter adapter) { if (convertView != null) { if (adapter.onSelect(marker, convertView, false)) { mapboxMap.selectMarker(marker); } marker.setSelected(true); convertView.bringToFront(); } } /** * Get view representation from a MarkerView. ** If marker is not found in current viewport, null is returned. *
* * @param marker the marker to get the view for * @return the android SDK View object */ @Nullable public View getView(MarkerView marker) { return markerViewMap.get(marker); } /** * Remove a MarkerView from a map. ** The {@link MarkerView} will be removed using an alpha animation and related {@link View} * will be released to the android.support.v4.util.Pools.SimplePool from the related * {@link com.mapbox.mapboxsdk.maps.MapboxMap.MarkerViewAdapter}. It's possible to remove * the {@link MarkerView} from the underlying collection if needed. *
* * @param marker the MarkerView to remove */ public void removeMarkerView(MarkerView marker) { boolean isAnimating = marker.isAnimating(); final View viewHolder = markerViewMap.get(marker); if (viewHolder != null && marker != null) { for (final MapboxMap.MarkerViewAdapter> adapter : markerViewAdapters) { if (adapter.getMarkerClass().equals(marker.getClass())) { if (!isAnimating) { if (adapter.prepareViewForReuse(marker, viewHolder)) { adapter.releaseView(viewHolder); } } } } } if (!isAnimating) { markerViewMap.remove(marker); } } /** * Add a MarkerViewAdapter to the MarkerViewManager. ** The provided MarkerViewAdapter must use supply a generic subclass of MarkerView. *
* * @param markerViewAdapter the MarkerViewAdapter to add */ public void addMarkerViewAdapter(MapboxMap.MarkerViewAdapter markerViewAdapter) { if (markerViewAdapter.getMarkerClass().equals(MarkerView.class)) { throw new RuntimeException("Providing a custom MarkerViewAdapter requires subclassing MarkerView"); } if (!markerViewAdapters.contains(markerViewAdapter)) { markerViewAdapters.add(markerViewAdapter); invalidateViewMarkersInBounds(); } } /** * Get all MarkerViewAdapters associated with this MarkerViewManager. * * @return a List of MarkerViewAdapters */ public List* This method is rate limited, and {@link #invalidateViewMarkersInBounds} will only be called * once each 250 ms. *
*/ public void scheduleViewMarkerInvalidation() { if (!markerViewAdapters.isEmpty()) { long currentTime = SystemClock.elapsedRealtime(); if (currentTime < viewMarkerBoundsUpdateTime) { return; } invalidateViewMarkersInBounds(); viewMarkerBoundsUpdateTime = currentTime + 250; } } /** * Invalidate the ViewMarkers found in the viewport. ** This method will remove any markers that aren't in the viewport any more and will add new * ones for each found Marker in the changed viewport. *
*/ public void invalidateViewMarkersInBounds() { Projection projection = mapboxMap.getProjection(); List