I have a GridMarkerClusterer
with some Marker
in it representing shared bike stations. I want those markers have a custom MarkerInfoWindow
(bubble) with a click listener so that when the user clicks on the bubble, a new intent is launched.
Thus far, I'm OK.
Now I want to put extra data (station information corresponding to the marker) to that intent.
What I actually did is to add a constructor in my StationMarkerInfoWindow
which takes a Station
in parameter. I then add this parameter to the intent with putExtra()
in my OnClickListener
.
That's working but what is wrong is that I need to create a new StationMarkerInfoWindow
for each marker instead of using the same object, and if I have more than 1000 markers to display, the activity takes up to 10 seconds to be created on my device (~1 second if I use the same StationMarkerInfoWindow
object for each marker).
The question is: how should I add those data to the intent?
Here are the relevant parts of the code:
public class MapActivity extends Activity {
private BikeNetwork bikeNetwork;
private ArrayList<Station> stations;
private MapView map;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_map);
// ...
stations = bikeNetwork.getStations();
map = (MapView) findViewById(R.id.mapView);
GridMarkerClusterer stationsMarkers = new GridMarkerClusterer(this);
Drawable clusterIconD = getResources().getDrawable(R.drawable.marker_cluster);
Bitmap clusterIcon = ((BitmapDrawable) clusterIconD).getBitmap();
map.getOverlays().add(stationsMarkers);
stationsMarkers.setIcon(clusterIcon);
stationsMarkers.setGridSize(100);
for (final Station station : stations) {
stationsMarkers.add(createStationMarker(station));
}
// ...
}
private Marker createStationMarker(Station station) {
Marker marker = new Marker(map);
marker.setInfoWindow(new StationMarkerInfoWindow(
R.layout.bonuspack_bubble, map, station)); // this seems wrong
marker.setInfoWindow(stationMarkerInfoWindow);
marker.setPosition(stationLocation);
marker.setAnchor(Marker.ANCHOR_CENTER, Marker.ANCHOR_CENTER);
marker.setIcon(getResources().getDrawable(R.drawable.ic_bike));
marker.setTitle(station.getName());
marker.setSnippet(String.valueOf(station.getFreeBikes())); // free bikes
marker.setSubDescription(String.valueOf(station.getEmptySlots())); // empty slots
return marker;
}
private class StationMarkerInfoWindow extends MarkerInfoWindow {
Station station;
public StationMarkerInfoWindow(int layoutResId, final MapView mapView, final Station station) {
super(layoutResId, mapView);
this.station = station;
}
@Override
public void onOpen(Object item) {
super.onOpen(item);
closeAllInfoWindowsOn(map);
LinearLayout layout = (LinearLayout) getView().findViewById(R.id.map_bubble_layout);
layout.setClickable(true);
layout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(MapActivity.this, StationActivity.class);
intent.putExtra("station", station);
startActivity(intent);
}
});
}
}
}
I would suggest to set the Station as the "related object" of its Marker:
marker.setRelatedObject(station);
You can then retrieve this related object in StationMarkerInfoWindow#onOpen:
Marker marker = (Marker)item;
selectedStation = (Station)marker.getRelatedObject();
Similar implementation can be found here.
Then you can share the same StationMarkerInfoWindow.