-Update seit 2016 August
Zusammenfassung die richtige Antwort jetzt dieses Problem die neuen onCameraIdle
, statt OnCameraChangeListener
, die jetzt deprecated zu bedienen ist. Lesen Sie weiter wie.
Jetzt können Sie Ereignisse wie "dragEnd" und sogar andere Ereignisse auf der neuesten Version von Google Maps für Android hören.
Wie in der docs gezeigt, können Sie das Problem von mehreren (auch bekannt als „mehrere“) Anrufe des OnCameraChangeListener
durch die Verwendung der neuen Hörer vermeiden. Zum Beispiel können Sie jetzt überprüfen, was der Grund für die Kamerabewegung ist, was ideal ist, um mit einem fetchData
Problem wie gewünscht zu koppeln. Der folgende Code stammt größtenteils direkt aus den Dokumenten. Noch eine Sache, es ist notwendig, zu verwenden.
public class MyCameraActivity extends FragmentActivity implements
OnCameraMoveStartedListener,
OnCameraMoveListener,
OnCameraMoveCanceledListener,
OnCameraIdleListener,
OnMapReadyCallback {
private GoogleMap mMap;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my_camera);
SupportMapFragment mapFragment =
(SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
}
@Override
public void onMapReady(GoogleMap map) {
mMap = map;
mMap.setOnCameraIdleListener(this);
mMap.setOnCameraMoveStartedListener(this);
mMap.setOnCameraMoveListener(this);
mMap.setOnCameraMoveCanceledListener(this);
// Show Sydney on the map.
mMap.moveCamera(CameraUpdateFactory
.newLatLngZoom(new LatLng(-33.87365, 151.20689), 10));
}
@Override
public void onCameraMoveStarted(int reason) {
if (reason == OnCameraMoveStartedListener.REASON_GESTURE) {
Toast.makeText(this, "The user gestured on the map.",
Toast.LENGTH_SHORT).show();
} else if (reason == OnCameraMoveStartedListener
.REASON_API_ANIMATION) {
Toast.makeText(this, "The user tapped something on the map.",
Toast.LENGTH_SHORT).show();
} else if (reason == OnCameraMoveStartedListener
.REASON_DEVELOPER_ANIMATION) {
Toast.makeText(this, "The app moved the camera.",
Toast.LENGTH_SHORT).show();
}
}
@Override
public void onCameraMove() {
Toast.makeText(this, "The camera is moving.",
Toast.LENGTH_SHORT).show();
}
@Override
public void onCameraMoveCanceled() {
Toast.makeText(this, "Camera movement canceled.",
Toast.LENGTH_SHORT).show();
}
@Override
public void onCameraIdle() {
Toast.makeText(this, "The camera has stopped moving. Fetch the data from the server!", Toast.LENGTH_SHORT).show();
LatLngBounds bounds = mMap.getProjection().getVisibleRegion().latLngBounds;
fetchData(bounds)
}
}
Behelfslösung für eine effiziente Lösung vor 2016 August richtig
Da die Frage beantwortet wird, würde Ich mag auf, dass auf einer wahrscheinlichen nächsten Ausgabe sein hinzuzufügen.
Das Problem tritt auf, wenn Sie OnCameraChangeListener
verwenden, um Daten vom Server abzurufen, aufgrund der Häufigkeit, mit der diese Methode ausgelöst wird.
Es ein issue wie crazily häufig diese Methode trigged gemeldet ist, wenn Gleiten eine einfache Karte zu tun, also im Beispiel der Frage, wäre es fetchData
mehr aufeinander folgende Zeiten für sehr kleine Kamera Veränderungen auslösen, auch für keine Kamera ändert Ja, es kommt vor, dass sich die Grenzen der Kamera nicht geändert haben, aber die Methode wird ausgelöst.
Dies könnte sich auf die Leistung auf der Serverseite auswirken und würde viele Ressourcen der Geräte verschwenden, indem Daten sequenziell vom Server mehrmals abgerufen werden.
Sie können in diesem Link Problemumgehungen für dieses Problem finden, aber es gibt noch keine offizielle Möglichkeit, dies zu tun, z. B. mit einer wünschenswerten dragEnd
oder cameraChangeEnd
Rückrufe.
Ein Beispiel unten, bezogen auf die, die von dort, ist, wie ich das oben genannte Problem vermeiden, indem sie mit dem Zeitintervall der Anrufe zu spielen und die Anrufe mit den gleichen Grenzen zu verwerfen.
// Keep the current camera bounds
private LatLngBounds currentCameraBounds;
new GoogleMap.OnCameraChangeListener() {
private static int CAMERA_MOVE_REACT_THRESHOLD_MS = 500;
private long lastCallMs = Long.MIN_VALUE;
@Override
public void onCameraChange(CameraPosition cameraPosition) {
LatLngBounds bounds = map.getProjection().getVisibleRegion().latLngBounds;
// Check whether the camera changes report the same boundaries (?!), yes, it happens
if (currentCameraBounds.northeast.latitude == bounds.northeast.latitude
&& currentCameraBounds.northeast.longitude == bounds.northeast.longitude
&& currentCameraBounds.southwest.latitude == bounds.southwest.latitude
&& currentCameraBounds.southwest.longitude == bounds.southwest.longitude) {
return;
}
final long snap = System.currentTimeMillis();
if (lastCallMs + CAMERA_MOVE_REACT_THRESHOLD_MS > snap) {
lastCallMs = snap;
return;
}
fetchData(bounds);
lastCallMs = snap;
currentCameraBounds = bounds;
}
Sehr gut! Das rettete mir wahrscheinlich mehrere Stunden Arbeit zu verstehen und dann dieses Problem zu lösen. Danke! – EZDsIt
@EZDsSie sind herzlich willkommen! – Eduardo
Sie sollten auch nach 'null' für das Feld' currentCameraBounds' suchen. –