korujzade korujzade - 2 months ago 15
Android Question

How to make OnclickListener work right inside for loop?

I have an hashmap of (Integer; PlayerMarkerAndStatus) pair for storing Player id and PlayerMarkerAndStatus object. PlayerMarkerAndStatus has a marker and current status for player id specified in HashMap.

I also have volley request to API which returns details of each player of hashmap on success case of Volley -

OnSuccess(Player2 nearbyPlayer)
. Those data is supposed to be sent to a fragment when a marker is clicked -
onMarkerClick(Marker marker)
.

It compares a clicked marker and a marker from the hashmap. If they have equal marker IDs, it sends this player's details to the fragment. However, OnMarkerClickListener only takes the last marker of HashMap to compare with a clicked marker.

It is my code below:

for (final Map.Entry<Integer, PlayerMarkerAndStatus> e :
player_id_marker_status.entrySet()) {
Log.d(LOG_TAG, "marker id of current entry: " + e.getValue().getMarker().getId());
getNearbyPlayerDetails(new VolleyCallbackNearbyPlayerDetails() {
@Override
public void onSuccess(final Player2 nearbyPlayer) {
mMap.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener() {
@Override
public boolean onMarkerClick(Marker marker) {
Log.d(LOG_TAG, "clicked marker id: " + marker.getId());
Log.d(LOG_TAG, "current marker id: " + e.getValue().getMarker().getId());

if (marker.getId().equals(e.getValue().getMarker().getId())) {
Log.d(LOG_TAG, "marker clicked. Player id: " + e.getKey());

PlayerDetailsFragment playerDetailsFragment =
new PlayerDetailsFragment();

Bundle bundle = new Bundle();
bundle.putString("player_details_username",
nearbyPlayer.getSurname());
if (nearbyPlayer.getType() == -1)
bundle.putString("player_details_type", "a");
else {
bundle.putString("player__details_type", "b");
}
bundle.putInt("player_details_health",
nearbyPlayer.getHealth());

playerDetailsFragment.setArguments(bundle);
getSupportFragmentManager().beginTransaction()
.add(R.id.player_details_fragment_container,
playerDetailsFragment).commit();

return true;
}
return false;
}
});
}
}, e.getKey());
}


Logs of HashMap:

09-22 11:37:42.410 23553-23553/com.orujzade.asdf D/MainActivity: marker id of current entry: m3
09-22 11:37:42.415 23553-23553/com.orujzade.asdf D/MainActivity: marker id of current entry: m2
09-22 11:37:42.415 23553-23553/com.orujzade.asdf D/MainActivity: marker id of current entry: m1


Logs on marker click:

09-22 11:39:15.353 23553-23553/com.orujzade.asdf D/MainActivity: clicked marker id: m3
09-22 11:39:15.353 23553-23553/com.orujzade.asdf D/MainActivity: current marker id: m1
09-22 11:39:20.593 23553-23553/com.orujzade.asdf D/MainActivity: clicked marker id: m2
09-22 11:39:20.593 23553-23553/com.orujzade.asdf D/MainActivity: current marker id: m1
09-22 11:39:25.593 23553-23553/com.orujzade.asdf D/MainActivity: clicked marker id: m4
09-22 11:39:25.593 23553-23553/com.orujzade.asdf D/MainActivity: current marker id: m1


How can I make
OnMarkerClickListener
take a right marker from the hashmap?

Answer

Define one HashMap into class level to get player from marker id :

HashMap<String, Player2> playerMap = new HashMap<>();

Iterate HashMap and get player from above define method :

for (final Map.Entry<Integer, PlayerMarkerAndStatus> e : player_id_marker_status.entrySet()) {
     Log.d(LOG_TAG, "marker id of current entry: " + e.getValue().getMarker().getId());
     getNearbyPlayer(e.getKey(),e.getValue().getMarker().getId());
}

Define one method to get player using volley request and set player into HashMap using marker as key :

public void getNearbyPlayer(Integer playerId,final String markerId) {
        getNearbyPlayerDetails(new VolleyCallbackNearbyPlayerDetails() {
            @Override
            public void onSuccess(final Player2 nearbyPlayer) {
                playerMap.put(markerId, nearbyPlayer);
            }
        },playerId);
}

At last define marker click listener and get player from marker id :

mMap.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener() {
       @Override
       public boolean onMarkerClick(Marker marker) {
          Log.d(LOG_TAG, "clicked marker id: " + marker.getId());
          Player2 nearbyPlayer = playerMap.get(marker.getId());
          PlayerDetailsFragment playerDetailsFragment = new PlayerDetailsFragment();
          Bundle bundle = new Bundle();
          bundle.putString("player_details_username", nearbyPlayer.getSurname());
          if (nearbyPlayer.getType() == -1){ 
              bundle.putString("player_details_type", "a");
          }else {
              bundle.putString("player__details_type", "b");
          }
          bundle.putInt("player_details_health", nearbyPlayer.getHealth());
          playerDetailsFragment.setArguments(bundle);
          getSupportFragmentManager().beginTransaction().add(R.id.player_details_fragment_container, playerDetailsFragment).commit();
          return true;
      }
});
Comments