All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.mapbox.mapboxsdk.annotations.MarkerViewManager Maven / Gradle / Ivy

There is a newer version: 9.2.1
Show newest version
package com.mapbox.mapboxsdk.annotations;

import android.graphics.PointF;
import android.os.SystemClock;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.util.Pools;
import android.view.View;

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;

public class MarkerViewManager {

    private Map mMarkerViewMap;
    private MapboxMap mapboxMap;
    private MapView mapView;
    private List markerViewAdapters;
    private long mViewMarkerBoundsUpdateTime;
    private MapboxMap.OnMarkerViewClickListener onMarkerViewClickListener;

    public MarkerViewManager(@NonNull MapboxMap mapboxMap, @NonNull MapView mapView) {
        this.mapboxMap = mapboxMap;
        this.markerViewAdapters = new ArrayList<>();
        this.mapView = mapView;
        mMarkerViewMap = new HashMap<>();
    }

    public void animateRotation(@NonNull MarkerView marker, float rotation) {
        View convertView = mMarkerViewMap.get(marker);
        if (convertView != null) {
            AnimatorUtils.rotate(convertView, rotation);
        }
    }

    public void animateAlpha(@NonNull MarkerView marker, float alpha) {
        View convertView = mMarkerViewMap.get(marker);
        if (convertView != null) {
            AnimatorUtils.alpha(convertView, alpha);
        }
    }

    public void animateVisible(@NonNull MarkerView marker, boolean visible) {
        View convertView = mMarkerViewMap.get(marker);
        if (convertView != null) {
            convertView.setVisibility(visible ? View.VISIBLE : View.GONE);
        }
    }

    public void update() {
        View convertView;
        for (MarkerView marker : mMarkerViewMap.keySet()) {
            convertView = mMarkerViewMap.get(marker);
            if (convertView != null) {
                PointF point = mapboxMap.getProjection().toScreenLocation(marker.getPosition());
                int x = (int) (marker.getAnchorU() * convertView.getMeasuredWidth());
                int y = (int) (marker.getAnchorV() * convertView.getMeasuredHeight());
                marker.setOffsetX(x);
                marker.setOffsetY(y);
                convertView.setX(point.x - x);
                convertView.setY(point.y - y);

                if (marker.isVisible() && convertView.getVisibility() == View.GONE) {
                    convertView.animate().cancel();
                    convertView.setAlpha(0);
                    AnimatorUtils.alpha(convertView, 1);
                }
            }
        }
    }

    public void setTilt(float tilt) {
        View convertView;
        for (MarkerView markerView : mMarkerViewMap.keySet()) {
            if (markerView.isFlat()) {
                convertView = mMarkerViewMap.get(markerView);
                if (convertView != null) {
                    markerView.setTilt(tilt);
                    convertView.setRotationX(tilt);
                }
            }
        }
    }

    public void deselect(@NonNull MarkerView marker) {
        final View convertView = mMarkerViewMap.get(marker);
        if (convertView != null) {
            int deselectAnimatorRes = marker.getDeselectAnimRes();
            if (deselectAnimatorRes != 0) {
                AnimatorUtils.animate(convertView, deselectAnimatorRes);
            }
        }
    }

    public void removeMarkerView(MarkerView marker, boolean removeFromMap) {
        final View viewHolder = mMarkerViewMap.get(marker);
        if (viewHolder != null && marker != null) {
            for (final MapboxMap.MarkerViewAdapter adapter : markerViewAdapters) {
                if (adapter.getMarkerClass() == marker.getClass()) {

                    // get pool of Views associated to an adapter
                    final Pools.SimplePool viewPool = adapter.getViewReusePool();

                    // cancel ongoing animations
                    viewHolder.animate().cancel();
                    viewHolder.setAlpha(1);
                    AnimatorUtils.alpha(viewHolder, 0, new AnimatorUtils.OnAnimationEndListener() {
                        @Override
                        public void onAnimationEnd() {
                            viewHolder.setVisibility(View.GONE);
                            viewPool.release(viewHolder);
                        }
                    });
                }
            }
        }
        if (removeFromMap) {
            mMarkerViewMap.remove(marker);
        }
    }

    public void addMarkerViewAdapter(@Nullable MapboxMap.MarkerViewAdapter markerViewAdapter) {
        if (!markerViewAdapters.contains(markerViewAdapter)) {
            markerViewAdapters.add(markerViewAdapter);
            invalidateViewMarkersInBounds();
        }
    }

    public void setOnMarkerViewClickListener(@Nullable MapboxMap.OnMarkerViewClickListener listener) {
        onMarkerViewClickListener = listener;
    }

    public List getMarkerViewAdapters() {
        return markerViewAdapters;
    }

    public void invalidateViewMarkers() {
        if (!markerViewAdapters.isEmpty()) {
            long currentTime = SystemClock.elapsedRealtime();
            if (currentTime < mViewMarkerBoundsUpdateTime) {
                return;
            }
            invalidateViewMarkersInBounds();
            mViewMarkerBoundsUpdateTime = currentTime + 250;
        }
    }

    public void invalidateViewMarkersInBounds() {
        Projection projection = mapboxMap.getProjection();
        List markers = mapView.getMarkerViewsInBounds(projection.getVisibleRegion().latLngBounds);
        View convertView;

        // remove old markers
        Iterator iterator = mMarkerViewMap.keySet().iterator();
        while (iterator.hasNext()) {
            MarkerView m = iterator.next();
            if (!markers.contains(m)) {
                // remove marker
                convertView = mMarkerViewMap.get(m);
                int deselectAnimRes = m.getDeselectAnimRes();
                if (deselectAnimRes != 0) {
                    AnimatorUtils.animate(convertView, deselectAnimRes, 0);
                }
                removeMarkerView(m, false);
                iterator.remove();
            }
        }

        // introduce new markers
        for (final MarkerView marker : markers) {
            if (!mMarkerViewMap.containsKey(marker)) {
                for (final MapboxMap.MarkerViewAdapter adapter : markerViewAdapters) {
                    if (adapter.getMarkerClass() == marker.getClass()) {
                        convertView = (View) adapter.getViewReusePool().acquire();
                        final View adaptedView = adapter.getView(marker, convertView, mapView);
                        if (adaptedView != null) {

                            // tilt
                            adaptedView.setRotationX(marker.getTilt());

                            // rotation
                            adaptedView.setRotation(marker.getRotation());

                            // alpha
                            adaptedView.setAlpha(marker.getAlpha());

                            // visible
                            adaptedView.setVisibility(marker.isVisible() ? View.VISIBLE : View.GONE);

                            if (mapboxMap.getSelectedMarkers().contains(marker)) {
                                // if a marker to be shown was selected
                                // replay that animation with duration 0
                                int selectAnimRes = marker.getSelectAnimRes();
                                if (selectAnimRes != 0) {
                                    AnimatorUtils.animate(convertView, selectAnimRes, 0);
                                }
                            }

                            final int animSelectRes = marker.getSelectAnimRes();
                            adaptedView.setOnClickListener(new View.OnClickListener() {
                                @Override
                                public void onClick(final View v) {
                                    boolean clickHandled = false;
                                    if (onMarkerViewClickListener != null) {
                                        clickHandled = onMarkerViewClickListener.onMarkerClick(marker, v, adapter);
                                    }

                                    if (!clickHandled) {
                                        // InfoWindow offset
                                        int infoWindowOffsetX = (int) ((adaptedView.getWidth() * marker.getInfoWindowAnchorU()) - marker.getOffsetX());
                                        int infoWindowOffsetY = (int) ((adaptedView.getHeight() * marker.getInfoWindowAnchorV()) -marker.getOffsetY());
                                        marker.setTopOffsetPixels(infoWindowOffsetY);
                                        marker.setRightOffsetPixels(infoWindowOffsetX);

                                        if (animSelectRes != 0) {
                                            AnimatorUtils.animate(v, animSelectRes, new AnimatorUtils.OnAnimationEndListener() {
                                                @Override
                                                public void onAnimationEnd() {
                                                    mapboxMap.selectMarker(marker);
                                                }
                                            });
                                        } else {
                                            mapboxMap.selectMarker(marker);
                                        }
                                    }
                                }
                            });

                            mMarkerViewMap.put(marker, adaptedView);
                            if (convertView == null) {
                                mapView.addView(adaptedView);
                            }
                        }
                    }
                }
            }
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy