Skip to content
This repository has been archived by the owner on Aug 8, 2023. It is now read-only.

[android] - callback for asynchronous adding of a MarkerView #7239

Merged
merged 1 commit into from
Nov 30, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,6 @@ public void select(@NonNull MarkerView marker, View convertView, MapboxMap.Marke
select(marker, convertView, adapter, true);
}


/**
* Animate a MarkerView to a selected state.
* <p>
Expand All @@ -296,22 +295,33 @@ public void select(@NonNull MarkerView marker, View convertView, MapboxMap.Marke
}

/**
* Get view representation from a MarkerView. If marker is not found in current viewport,
* {@code null} is returned.
* Get the View representation for a MarkerView.
* <p>
* Note that this method returns null in following situations:
* </p>
* <p><ul>
* <li>The MarkerView isn't rendered yet, adding a marker is an asynchronous operation</li>
* <li>The MarkerView isn't found in the Map viewport, related View has been recycled</li>
* </ul><p>
* <p>
* To handle the asynchronous addition, you can register to Map change events with
* {@link MapView#addOnMapChangedListener(MapView.OnMapChangedListener)} and validate if
* the View has been added.
* </p>
*
* @param marker the marker to get the view.
* @return the Android SDK View object.
* @param marker the marker to get the view representation for
* @return the android SDK View representing the MarkerView
*/
@Nullable
public View getView(MarkerView marker) {
return markerViewMap.get(marker);
}

/**
* Get the view adapter for a marker.
* Get the MarkerViewAdapter for a MarkerView.
*
* @param markerView the marker to get the view adapter.
* @return the MarkerView adapter.
* @param markerView the MarkerView to get the adapter for
* @return the MarkerViewAdapter is there is one available for the provided MarkerView
*/
@Nullable
public MapboxMap.MarkerViewAdapter getViewAdapter(MarkerView markerView) {
Expand Down Expand Up @@ -579,4 +589,21 @@ private static class ViewHolder {
ImageView imageView;
}
}

/**
* Interface definition invoked when the View of a MarkerView has been added to the map.
* <p>
* This callback will be invoked as a result of {@link MapboxMap#addMarker(BaseMarkerOptions)}
* and only when the related MarkerView is found in the viewport of the map.
* </p>
*/
public interface OnMarkerViewAddedListener {

/**
* Invoked when the View of a MarkerView has been added to the Map.
*
* @param markerView The MarkerView the View was added for
*/
void onViewAdded(@NonNull MarkerView markerView);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1252,6 +1252,10 @@ List<Marker> getMarkersInRect(@NonNull RectF rectangle) {

/**
* Use to determine which {@link MarkerView}s are found within a given {@link RectF}
* <p>
* Note that adding a Marker is an asynchronous operation and requires the map to render first
* before querying the map for them.
* </p>
*
* @param rectangle Holds four float coordinates for a rectangle.
* @return The list of {@link MarkerView}s found within the provided {@link RectF}.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1034,19 +1034,41 @@ public Marker addMarker(@NonNull BaseMarkerOptions markerOptions) {
@UiThread
@NonNull
public MarkerView addMarker(@NonNull BaseMarkerViewOptions markerOptions) {
return addMarker(markerOptions, null);
}

/**
* <p>
* Adds a marker to this map.
* </p>
* The marker's icon is rendered on the map at the location {@code Marker.position}.
* If {@code Marker.title} is defined, the map shows an info box with the marker's title and snippet.
*
* @param markerOptions A marker options object that defines how to render the marker.
* @param onMarkerViewAddedListener Callback invoked when the View has been added to the map.
* @return The {@code Marker} that was added to the map.
*/
@UiThread
@NonNull
public MarkerView addMarker(@NonNull BaseMarkerViewOptions markerOptions, final MarkerViewManager.OnMarkerViewAddedListener onMarkerViewAddedListener) {
final MarkerView marker = prepareViewMarker(markerOptions);

// listen for a render event, so we can invalidate MarkerViews
mapView.addOnMapChangedListener(new MapView.OnMapChangedListener() {
@Override
public void onMapChanged(@MapView.MapChange int change) {
if (change == MapView.DID_FINISH_RENDERING_FRAME_FULLY_RENDERED) {
markerViewManager.invalidateViewMarkersInVisibleRegion();
if(onMarkerViewAddedListener !=null && markerViewManager.getView(marker)!=null){
// checking if view is also found in current viewport.
onMarkerViewAddedListener.onViewAdded(marker);
}
mapView.removeOnMapChangedListener(this);
}
}
});

// add marker to map
MarkerView marker = prepareViewMarker(markerOptions);
marker.setMapboxMap(this);
long id = mapView.addMarker(marker);
marker.setId(id);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import com.mapbox.mapboxsdk.annotations.IconFactory;
import com.mapbox.mapboxsdk.annotations.Marker;
import com.mapbox.mapboxsdk.annotations.MarkerView;
import com.mapbox.mapboxsdk.annotations.MarkerViewManager;
import com.mapbox.mapboxsdk.annotations.MarkerViewOptions;
import com.mapbox.mapboxsdk.camera.CameraPosition;
import com.mapbox.mapboxsdk.geometry.LatLng;
Expand Down Expand Up @@ -62,13 +63,20 @@ public void onMapReady(@NonNull final MapboxMap mapboxMap) {
AnimatedMarkerActivity.this.mapboxMap = mapboxMap;
setupMap();

for (int i = 0; i < 10; i++) {
addRandomCar();
}

addPassenger();
addMainCar();
animateMoveToPassenger(carMarker);
// posting update to end of message queue due to LatLngBounds issue,
// view is not measured yet, bounds = 0
// else all cars start from top left
mapView.post(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 10; i++) {
addRandomCar();
}

addPassenger();
addMainCar();
}
});
}
});
}
Expand Down Expand Up @@ -99,13 +107,17 @@ private void addMainCar() {
LatLng randomLatLng = getLatLngInBounds();

if (carMarker == null) {
carMarker = createCarMarker(randomLatLng, R.drawable.ic_taxi_top);
carMarker = createCarMarker(randomLatLng, R.drawable.ic_taxi_top, new MarkerViewManager.OnMarkerViewAddedListener() {
@Override
public void onViewAdded(@NonNull MarkerView markerView) {
// Make sure the car marker is selected so that it's always brought to the front (#5285)
mapboxMap.selectMarker(carMarker);
animateMoveToPassenger(carMarker);
}
});
} else {
carMarker.setPosition(randomLatLng);
}

// Make sure the car marker is selected so that it's always brought to the front (#5285)
mapboxMap.selectMarker(carMarker);
}

private void animateMoveToPassenger(final MarkerView car) {
Expand All @@ -120,8 +132,12 @@ public void onAnimationEnd(Animator animation) {
}

protected void addRandomCar() {
MarkerView car = createCarMarker(getLatLngInBounds(), R.drawable.ic_car_top);
randomlyMoveMarker(car);
createCarMarker(getLatLngInBounds(), R.drawable.ic_car_top, new MarkerViewManager.OnMarkerViewAddedListener(){
@Override
public void onViewAdded(@NonNull MarkerView markerView) {
randomlyMoveMarker(markerView);
}
});
}

private void randomlyMoveMarker(final MarkerView marker) {
Expand Down Expand Up @@ -150,14 +166,14 @@ private ValueAnimator animateMoveMarker(final MarkerView marker, LatLng to) {
return markerAnimator;
}

private MarkerView createCarMarker(LatLng start, @DrawableRes int carResource) {
private MarkerView createCarMarker(LatLng start, @DrawableRes int carResource, MarkerViewManager.OnMarkerViewAddedListener listener) {
Icon icon = IconFactory.getInstance(AnimatedMarkerActivity.this)
.fromResource(carResource);

//View Markers
return mapboxMap.addMarker(new MarkerViewOptions()
.position(start)
.icon(icon));
.icon(icon),listener);

//GL Markers
// return mapboxMap.addMarker(new MarkerOptions()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,12 @@
import android.view.View;
import android.widget.SeekBar;
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.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;
Expand All @@ -25,7 +27,9 @@ public class MarkerViewScaleActivity extends AppCompatActivity implements OnMapR

private MapboxMap mapboxMap;
private MapView mapView;
private View markerView;

private MarkerView markerView;
private MarkerViewManager markerViewManager;

@Override
protected void onCreate(Bundle savedInstanceState) {
Expand All @@ -41,10 +45,6 @@ protected void onCreate(Bundle savedInstanceState) {
actionBar.setDisplayShowHomeEnabled(true);
}

final SeekBar xBar = (SeekBar) findViewById(R.id.seekbar_factor);
TextView textView = (TextView) findViewById(R.id.textview_factor);
xBar.setOnSeekBarChangeListener(new FactorChangeListener(textView));

mapView = (MapView) findViewById(R.id.mapView);
mapView.onCreate(savedInstanceState);
mapView.getMapAsync(this);
Expand All @@ -53,17 +53,40 @@ protected void onCreate(Bundle savedInstanceState) {
@Override
public void onMapReady(MapboxMap map) {
mapboxMap = map;
markerViewManager = map.getMarkerViewManager();

final SeekBar xBar = (SeekBar) findViewById(R.id.seekbar_factor);
final TextView textView = (TextView) findViewById(R.id.textview_factor);

// We need to listen to a render event to be sure
// the View of the Marker has been added to the map
mapView.addOnMapChangedListener(new MapView.OnMapChangedListener() {
@Override
public void onMapChanged(@MapView.MapChange int change) {
if (isMarkerRendered()) {
Toast.makeText(MarkerViewScaleActivity.this, "MarkerView is ready", Toast.LENGTH_SHORT).show();
View view = markerViewManager.getView(markerView);
xBar.setOnSeekBarChangeListener(new FactorChangeListener(view, textView));
xBar.setClickable(true);
mapView.removeOnMapChangedListener(this);
}
}

private boolean isMarkerRendered() {
return markerView != null && markerViewManager.getView(markerView) != null;
}
});

Icon icon = IconFactory.getInstance(MarkerViewScaleActivity.this)
.fromResource(R.drawable.ic_circle);

MarkerView marker = mapboxMap.addMarker(new MarkerViewOptions()
markerView = mapboxMap.addMarker(new MarkerViewOptions()
.position(new LatLng(38.907192, -77.036871))
.icon(icon)
.flat(true));

markerView = mapboxMap.getMarkerViewManager().getView(marker);
}


@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
Expand Down Expand Up @@ -105,21 +128,23 @@ public void onLowMemory() {
mapView.onLowMemory();
}

private class FactorChangeListener implements SeekBar.OnSeekBarChangeListener {
private static class FactorChangeListener implements SeekBar.OnSeekBarChangeListener {

private TextView textView;
private View view;

public FactorChangeListener(TextView textView) {
FactorChangeListener(View view, TextView textView) {
this.view = view;
this.textView = textView;
}

@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
float newScale = getScale(progress);
textView.setText(String.format(Locale.US, "Scale: %.1f", newScale));
if (MarkerViewScaleActivity.this.markerView != null) {
markerView.setScaleX(newScale);
markerView.setScaleY(newScale);
if (view != null) {
view.setScaleX(newScale);
view.setScaleY(newScale);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
android:layout_height="wrap_content"
android:layout_below="@id/title"
android:layout_marginLeft="56dp"
android:clickable="false"
android:progress="0" />

</RelativeLayout>
Expand Down