使用动态打开 AlertDialog 的 onClickListener 创建标记

Creating markers with onClickListener that opens AlertDialog dynamically

我正在尝试向地图动态添加标记,从 JSON 获取数据,这部分工作正常,我可以在多个地方添加多个标记,但是当我点击标记时,我想要打开警报对话框,此警报对话框必须包含有关该标记的一些信息,但现在我拥有的信息始终相同,就像警报对话框的创建不在创建标记的同一周期中一样.

查看我的代码:

final JSONArray array = new JSONArray(jsonStrOportunidades);
for (int i = 0; i < array.length(); i++)
{
    JSONObject jsonObject = array.getJSONObject(i);
    final String Designacao = jsonObject.getString("Designacao");
    String Coord_LAT = jsonObject.getString("Coord_LAT");
    String Coord_LONG = jsonObject.getString("Coord_LONG");
    final String Morada = jsonObject.getString("Morada");

    final HashMap<String, String> oportunidades = new HashMap<>();

    oportunidades.put("Designacao", Designacao);
    oportunidades.put("Coord_LAT", Coord_LAT);
    oportunidades.put("Coord_LONG", Coord_LONG);
    oportunidades.put("Morada", Morada);

    double lat1 = Double.parseDouble(Coord_LAT);
    double lng1 = Double.parseDouble(Coord_LONG);

    mMap.addMarker(new MarkerOptions().position(new LatLng(lat1, lng1)));

    mMap.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener() {
        @Override
        public boolean onMarkerClick(Marker marker) {
            new AlertDialog.Builder(MapsActivity.this)
                    .setTitle(Designacao)
                    .setMessage("Endereço: " + Morada + "\n" + "Telefone: " )
                    .setPositiveButton("Ir", new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog, int which) {
                            new GetDirecoes().execute();//Enviar as coordenadas
                            mBottomSheetBehavior.setPeekHeight(250);
                        }
                    })
                    .setNegativeButton("Cancelar", new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog, int which) {
                            // do nothing
                        }
                    })
                    .show();
            return false;
        }
    });
    listaOportunidades.add(oportunidades);
} 

您在循环的每次迭代中对 GoogleMap 对象重新分配 GoogleMap.OnMapClickListener。因此,侦听器将具有 JSON 数组中最后一个对象的信息。确保只设置 OnMapClickListener 一次。

解决此问题的方法是将您的额外数据添加到标记中,并在侦听器中提取数据。

Marker marker = new MarkerOptions().position(new LatLng(lat1, lng1));
marker.setTag(extraInfo)

然后在监听器中

public boolean onMarkerClick(Marker marker) {
  ExtraInfo info = (ExtraInfo)marker.getTag();
}

每次方法

mMap.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener() {
        @Override
        public boolean onMarkerClick(Marker marker) {
            new AlertDialog.Builder(MapsActivity.this)
                    .setTitle(Designacao)
                    .setMessage("Endereço: " + Morada + "\n" + "Telefone: " )
                    .setPositiveButton("Ir", new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog, int which) {
                            new GetDirecoes().execute();//Enviar as coordenadas
                            mBottomSheetBehavior.setPeekHeight(250);
                        }
                    })
                    .setNegativeButton("Cancelar", new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog, int which) {
                            // do nothing
                        }
                    })
                    .show();
            return false;
        }
    });

被调用,它会覆盖您之前设置的 OnMarkerClickListener。出于这个原因,最终将最后一个 OnMarkerClickListener 设置为映射,这就是为什么它在每次点击时都提供相同的位置信息(最后一个位置的信息)。

为了解决该问题,您必须使用从 onMarkerClick(Marker marker) 方法接收的标记对象并将侦听器设置在循环外部。您可以将位置设置为标记的标签,稍后在 onMarkerClick(Marker marker) 中您可以检查位置并从 listaOportunidades 获取相关的地点信息。

Marker m = mMap.addMarker(new MarkerOptions().position(new LatLng(lat1, lng1)));
m.setTag(i);

以后

    mMap.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener() {
            @Override
            public boolean onMarkerClick(Marker marker) {
                int position = (int) marker.getTag();
// Show your alert dialog for the information related to the position
                return false;
            }
        });