package com.mapbox.mapboxsdk.testapp.activity.annotation; import android.animation.Animator; import android.animation.AnimatorInflater; import android.animation.AnimatorListenerAdapter; import android.animation.FloatEvaluator; import android.animation.ObjectAnimator; import android.animation.ValueAnimator; import android.content.Context; import android.os.Bundle; import android.os.Handler; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.v7.app.AppCompatActivity; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.TextView; import android.widget.Toast; import com.mapbox.mapboxsdk.annotations.Icon; import com.mapbox.mapboxsdk.annotations.IconFactory; import com.mapbox.mapboxsdk.annotations.Marker; import com.mapbox.mapboxsdk.annotations.MarkerOptions; import com.mapbox.mapboxsdk.annotations.MarkerView; import com.mapbox.mapboxsdk.annotations.MarkerViewManager; import com.mapbox.mapboxsdk.annotations.MarkerViewOptions; import com.mapbox.mapboxsdk.geometry.LatLng; import com.mapbox.mapboxsdk.maps.MapView; import com.mapbox.mapboxsdk.maps.MapboxMap; import com.mapbox.mapboxsdk.testapp.R; import com.mapbox.mapboxsdk.testapp.model.annotations.CountryMarkerView; import com.mapbox.mapboxsdk.testapp.model.annotations.CountryMarkerViewOptions; import com.mapbox.mapboxsdk.testapp.model.annotations.TextMarkerView; import com.mapbox.mapboxsdk.testapp.model.annotations.TextMarkerViewOptions; import java.util.Locale; import java.util.Random; /** * Test activity showcasing multiple MarkerViews above Washington D.C. *
* Shows a couple of open InfoWindows out of current Viewport. * Updates the rotation and location of a couple of MarkerViews. *
*/ public class MarkerViewActivity extends AppCompatActivity { private static final LatLng[] LAT_LNGS = new LatLng[] { new LatLng(38.897424, -77.036508), new LatLng(38.909698, -77.029642), new LatLng(38.907227, -77.036530), new LatLng(38.905607, -77.031916), new LatLng(38.889441, -77.050134), new LatLng(38.888000, -77.050000) // Slight overlap to show re-ordering on selection }; private MapboxMap mapboxMap; private MapView mapView; private TextView viewCountView; // MarkerView location updates private MarkerView movingMarkerOne; private MarkerView movingMarkerTwo; private Random randomAnimator = new Random(); private Handler locationUpdateHandler = new Handler(); private Runnable moveMarkerRunnable = new MoveMarkerRunnable(); // MarkerView rotate updates private MarkerView rotateMarker; private Handler rotateUpdateHandler = new Handler(); private Runnable rotateMarkerRunnable = new RotateMarkerRunnable(); private int rotation = 360; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_marker_view); viewCountView = (TextView) findViewById(R.id.countView); mapView = (MapView) findViewById(R.id.mapView); mapView.onCreate(savedInstanceState); mapView.getMapAsync(mapboxMap -> { MarkerViewActivity.this.mapboxMap = mapboxMap; final MarkerViewManager markerViewManager = mapboxMap.getMarkerViewManager(); Icon usFlag = IconFactory.getInstance(MarkerViewActivity.this) .fromResource(R.drawable.ic_us); // add default ViewMarker markers for (int i = 0; i < LAT_LNGS.length; i++) { MarkerViewActivity.this.mapboxMap.addMarker(new MarkerViewOptions() .position(LAT_LNGS[i]) .title(String.valueOf(i)) .alpha(0.5f) .icon(usFlag) ); } // add custom ViewMarker CountryMarkerViewOptions options = new CountryMarkerViewOptions(); options.flagRes(R.drawable.icon_burned); options.abbrevName("Mapbox"); options.title("Hello"); options.position(new LatLng(38.899774, -77.023237)); options.flat(true); MarkerView markerView = mapboxMap.addMarker(options); // Use object animator to rotate MarkerView ValueAnimator markerAnimator = ObjectAnimator.ofObject(markerView, "rotation", new FloatEvaluator(), -90, 90); markerAnimator.setDuration(5000); markerAnimator.start(); MarkerViewActivity.this.mapboxMap.addMarker(new MarkerOptions() .title("United States") .position(new LatLng(38.902580, -77.050102)) ); rotateMarker = MarkerViewActivity.this.mapboxMap.addMarker(new TextMarkerViewOptions() .text("A") .rotation(rotation = 270) .position(new LatLng(38.889876, -77.008849)) ); loopMarkerRotate(); MarkerViewActivity.this.mapboxMap.addMarker(new TextMarkerViewOptions() .text("B") .position(new LatLng(38.907327, -77.041293)) ); MarkerViewActivity.this.mapboxMap.addMarker(new TextMarkerViewOptions() .text("C") .position(new LatLng(38.897642, -77.041980)) ); // if you want to customise a ViewMarker you need to extend ViewMarker and provide an adapter implementation // set adapters for child classes of ViewMarker markerViewManager.addMarkerViewAdapter(new CountryAdapter(MarkerViewActivity.this, mapboxMap)); markerViewManager.addMarkerViewAdapter(new TextAdapter(MarkerViewActivity.this, mapboxMap)); // add a change listener to validate the size of amount of child views mapView.addOnCameraDidChangeListener(new MapView.OnCameraDidChangeListener() { @Override public void onCameraDidChange(boolean animated) { setViewCount(); } }); // add a OnMarkerView click listener MarkerViewActivity.this.mapboxMap.getMarkerViewManager().setOnMarkerViewClickListener( (marker, view, adapter) -> { Toast.makeText(MarkerViewActivity.this, "Hello " + marker.getId(), Toast.LENGTH_SHORT).show(); return false; }); movingMarkerOne = MarkerViewActivity.this.mapboxMap.addMarker(new MarkerViewOptions() .position(CarLocation.CAR_0_LNGS[0]) .icon(IconFactory.getInstance(mapView.getContext()) .fromResource(R.drawable.ic_android)) ); movingMarkerTwo = mapboxMap.addMarker(new MarkerViewOptions() .position(CarLocation.CAR_1_LNGS[0]) .icon(IconFactory.getInstance(mapView.getContext()) .fromResource(R.drawable.ic_android_2)) ); // allow more open infowindows at the same time mapboxMap.setAllowConcurrentMultipleOpenInfoWindows(true); // add offscreen markers Marker markerRightOffScreen = mapboxMap.addMarker(new MarkerOptions() .setPosition(new LatLng(38.892846, -76.909399)) .title("InfoWindow") .snippet("Offscreen, to the right of the Map.")); Marker markerRightBottomOffScreen = mapboxMap.addMarker(new MarkerOptions() .setPosition(new LatLng(38.791645, -77.039006)) .title("InfoWindow") .snippet("Offscreen, to the bottom of the Map")); // open infowindow offscreen markers mapboxMap.selectMarker(markerRightOffScreen); mapboxMap.selectMarker(markerRightBottomOffScreen); }); } private void setViewCount() { final MarkerViewManager markerViewManager = mapboxMap.getMarkerViewManager(); final ViewGroup markerViewContainer = markerViewManager.getMarkerViewContainer(); if (!markerViewManager.getMarkerViewAdapters().isEmpty() && viewCountView != null) { viewCountView.setText(String.format( Locale.getDefault(), getString(R.string.viewcache_size), markerViewContainer.getChildCount()) ); } } private void loopMarkerRotate() { rotateUpdateHandler.postDelayed(rotateMarkerRunnable, 800); } @Override protected void onStart() { super.onStart(); mapView.onStart(); loopMarkerMove(); } private void loopMarkerMove() { locationUpdateHandler.postDelayed(moveMarkerRunnable, randomAnimator.nextInt(3000) + 1000); } @Override protected void onStop() { super.onStop(); mapView.onStop(); locationUpdateHandler.removeCallbacks(moveMarkerRunnable); rotateUpdateHandler.removeCallbacks(rotateMarkerRunnable); } /** * Updates the position of a Marker */ private class MoveMarkerRunnable implements Runnable { @Override public void run() { int randomInteger = randomAnimator.nextInt(9); if (randomAnimator.nextInt() % 2 == 0) { movingMarkerOne.setPosition(CarLocation.CAR_0_LNGS[randomInteger]); } else { movingMarkerTwo.setPosition(CarLocation.CAR_1_LNGS[randomInteger]); } loopMarkerMove(); } } /** * Updates the rotation of a Marker */ private class RotateMarkerRunnable implements Runnable { private static final int ROTATION_INCREASE_VALUE = 9; @Override public void run() { rotation -= ROTATION_INCREASE_VALUE; if (rotation >= 0) { rotation += 360; } rotateMarker.setRotation(rotation); loopMarkerRotate(); } } /** * Adapts a MarkerView to display an abbreviated name in a TextView and a flag in an ImageView. */ private static class CountryAdapter extends MapboxMap.MarkerViewAdapter