我正在使用osmdroid库和android http请求。因此,我正在做的是用标记填充地图,其中经度和经度是从服务器上的数据库中获得的。问题id:如何在发出请求的方法之外调用marker.setOnClickListener。下面是我的代码:
RequestQueue queue = Volley.newRequestQueue(getApplicationContext());
StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
new Response.Listener<String>() {
@Override
public void onResponse(String response) {
try {
JSONArray obj = new JSONArray(response);
for (int i = 0; i < obj.length(); i++) {
JSONObject primer = obj.getJSONObject(i);
double latitud = primer.getDouble(TAG_Latitud);
double longitude = primer.getDouble(TAG_Longitude);
marker = new Marker(map);
marker.setPosition(new GeoPoint(latitud, longitude));
marker.setAnchor(Marker.ANCHOR_CENTER, Marker.ANCHOR_BOTTOM);
mHashMap.put(marker, i);
Terrenos.add(terrenos);
}
marker.setOnMarkerClickListener(new Marker.OnMarkerClickListener() {
@Override
public boolean onMarkerClick(Marker marker, MapView mapView) {
Intent intent = new Intent(Osmdroid.this, Activity2.class);
startActivity(intent);
return false;
}
});
map.getOverlays().add(marker);
} catch (JSONException e) {
Toast.makeText(Osmdroid.this,"Something Wrong", Toast.LENGTH_LONG).show();
Log.w("exception", e.toString());
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(Osmdroid.this,"Something Wrong",Toast.LENGTH_LONG).show();
Log.w("Error", "No hay respuesta en http");
}
});
queue.add(stringRequest);
}因此,在上面的代码中,我在“for”中创建了标记,并在完成时调用onClick方法。但当我这样做时,并不是所有的标记在单击时都起作用,只有最后一个创建。有人知道该怎么做吗?我真的很感谢你的帮助。
发布于 2018-04-12 03:08:52
只有最后一个标记有onClick,因为您只将它设置为它。在每次循环中,标记对象都会获得一个新的引用marker = new Marker(map);。正因为如此,在最后一个循环中,标记对象包含了最后一个引用,并且onClick方法只对其进行了设置。
要解决这个问题,只需在循环中设置onClick和map.getOverlays().add(marker)即可。
public void onResponse(String response) {
try {
JSONArray obj = new JSONArray(response);
for (int i = 0; i < obj.length(); i++) {
JSONObject primer = obj.getJSONObject(i);
double latitud = primer.getDouble(TAG_Latitud);
double longitude = primer.getDouble(TAG_Longitude);
marker = new Marker(map);
marker.setPosition(new GeoPoint(latitud, longitude));
marker.setAnchor(Marker.ANCHOR_CENTER, Marker.ANCHOR_BOTTOM);
map.getOverlays().add(marker);
mHashMap.put(marker, i);
Terrenos.add(terrenos);
marker.setOnMarkerClickListener(new Marker.OnMarkerClickListener() {
@Override
public boolean onMarkerClick(Marker marker, MapView mapView) {
Intent intent = new Intent(Osmdroid.this, Activity2.class);
startActivity(intent);
return false;
}
});
}发布于 2018-04-12 21:54:24
我将尝试详细地解释,你做错了什么,因为你似乎缺少了一些关于OOP编程,变量等的基础知识。
怎么了
您可以在循环中创建多个标记类型的对象,但名为marker的变量仅存储对一个标记类型对象的引用。在每次迭代期间,您将在循环末尾重用此变量。在每次迭代期间,您将分配Marker类的另一个实例( Marker类型的另一个对象,具有自己的个人内存块)。
循环结束后,您的变量仍然存在并指向一个对象-这是创建的最后一个标记实例,因为它是分配给名为marker的变量的最后一个值。您正在将OnMarkerClickListener分配给此唯一的对象。
如何修复它你想在你创建的每个标记实例上调用方法setOnMarkerClickListener (assign OnMarkerClickListener)。其方法与创建时相同:使用循环。这里基本上有两个选项:
1)重用已在代码中的循环,并在其中分配侦听器。这是最简单的解决方案,因为您只需在源代码中将赋值向上移动一点,它就会起作用:
for (int i = 0; i < obj.length(); i++) {
JSONObject primer = obj.getJSONObject(i);
double latitud = primer.getDouble(TAG_Latitud);
double longitude = primer.getDouble(TAG_Longitude);
marker = new Marker(map);
marker.setPosition(new GeoPoint(latitud, longitude));
marker.setAnchor(Marker.ANCHOR_CENTER, Marker.ANCHOR_BOTTOM);
mHashMap.put(marker, i);
Terrenos.add(terrenos);
marker.setOnMarkerClickListener(new Marker.OnMarkerClickListener() {
@Override
public boolean onMarkerClick(Marker marker, MapView mapView) {
Intent intent = new Intent(Osmdroid.this, Activity2.class);
startActivity(intent);
return false;
}
});
}
map.getOverlays().add(marker);然而,这并不是最好的方法。每个标记都会创建一个新的侦听器实例,因此会浪费一些内存。但是你可以在循环之前创建一个监听器的实例,将它存储在变量中,并将相同的对象分配给所有的标记。一旦你把事情做好了,试着把它弄清楚是一种改进。
2)你可以在某个地方存储标记并创建另一个循环,在这个循环中你将分配监听器。可以有一个变量(或类中的字段),其中包含所有标记的列表
List<Marker> markers = new ArrayList<>();在循环中,一旦创建了标记,就可以将其添加到此列表中:
for (int i = 0; i < obj.length(); i++) {
...
marker = new Marker(map);
marker.setPosition(new GeoPoint(latitud, longitude));
marker.setAnchor(Marker.ANCHOR_CENTER, Marker.ANCHOR_BOTTOM);
markers.add(marker); //addind to the listt
...然后,您可以在稍后迭代列表,并将侦听器分配给所有标记。试着自己弄清楚代码。与前面的情况类似:您可以为每个标记创建新的侦听器,也可以为所有标记重用一个侦听器。
最后一件事:你不需要像我上面提到的那样用list删除新的变量,因为你已经有了包含所有标记的字段。您将它们用作hasmmap中的键:
mHashMap.put(marker, i);我不知道这个哈希图的目的是什么,但您可以通过mHasnMap.keySet()访问所有标记(确切地说:访问具有所有标记的Set实例
https://stackoverflow.com/questions/49781966
复制相似问题