如何让 OnclickListener 在 for 循环中正常工作?

How to make OnclickListener work right inside for loop?

我有一个 (Integer; PlayerMarkerAndStatus) 对的哈希图,用于存储玩家 ID 和 PlayerMarkerAndStatus 对象。 PlayerMarkerAndStatus 具有在 HashMap 中指定的玩家 ID 的标记和当前状态。

我也有 volley 请求 API,其中 returns 每个 hashmap 玩家的详细信息在 Volley 的成功案例中 - OnSuccess(Player2 nearbyPlayer)。这些数据应该在单击标记时发送到片段 - onMarkerClick(Marker marker).

它比较点击的标记和哈希图中的标记。如果它们具有相同的标记 ID,它会将此玩家的详细信息发送到片段。然而,OnMarkerClickListener 只取 HashMap 的最后一个标记与点击的标记进行比较。

下面是我的代码:

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());
            }

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

标记点击记录:

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

如何让 OnMarkerClickListener 从 hashmap 中取一个正确的标记?

setOnMarkerClickListener 应该在循环之外。为玩家 ID 和 Player2 创建一个 hashmap idPlayerMap。在截击成功响应中,将 Player2 对象及其 ID 放入该地图中。在 MarkerClickListener 运行 循环中检查哪个标记被点击并从 idPlayerMap 获取相应的播放器并将其发送到所需的 Fragment.

 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());
                                          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());
                                              if (marker.getId().equals(e.getValue().getMarker().getId())) {
                                                  Log.d(LOG_TAG, "marker clicked. Player id: " + e.getKey());

                                                  PlayerDetailsFragment playerDetailsFragment =
                                                          new PlayerDetailsFragment();
                                                  Player2 nearbyPlayer = idPlayerMap.get(e.getKey());
                                                  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;
                                          }
                                      }
                                      HashMap<Integer, Player2> idPlayerMap =  new HashMap<Integer, Player2>();

    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(Player2 nearbyPlayer) {
                idPlayerMap.put(e.getKey(), nearbyPlayer);
                });
            }
        }
    }

定义一个 HashMap 到 class 关卡以从标记 id 获取玩家:

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

迭代HashMap并从上面获取播放器定义方法:

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());
}

定义一种使用截击请求获取玩家并使用标记作为键将玩家设置为 HashMap 的方法:

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

最后定义标记点击侦听器并从标记 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;
      }
});