更新自2016年八月
摘要的正确现在答案这个问题是使用新onCameraIdle
,而不是OnCameraChangeListener
,这是现在deprecated。读下面的话。
现在,您可以收听“dragEnd”式的活动,甚至可以收听最新版Android版Google地图上的其他活动。
正如docs所示,您可避免多次的问题(又名“几个”)的OnCameraChangeListener
通过使用新的听众来电。例如,您现在可以查看相机移动背后的原因,这是根据要求加上fetchData
问题的理想选择。以下代码大部分直接来自文档。还有一件事,有必要使用Google Play Services 9.4。 2016年8月
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)
}
}
解决方法了有效的解决方案之前,由于问题的正确回答,我想上添加一个可能是下一个问题。
当使用OnCameraChangeListener
从服务器获取数据时,由于触发此方法的频率而出现问题。
有报道关于如何疯狂地频繁出现问题的例子做一个简单的地图时滑动,因而这种方法被触发的issue,它会引发fetchData
多个连续的时间非常的小相机的变化,即使没有摄像头的变化,是的,碰巧相机边界没有改变,但方法被触发。
这可以在服务器端性能的影响,并会被从服务器获取数据连续数十倍浪费了大量的设备的资源。
您可以在该链接中找到此问题的解决方法,但尚未有官方的方式来执行此操作,例如,使用期望的dragEnd
或cameraChangeEnd
回调。
一个例子波纹管的基础上,从那里的人,是我如何通过与呼叫的时间间隔玩,放弃与同一边界的调用避免上述问题。
// 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;
}
非常好! 这可能为我节省了几个小时的工作理解,然后解决这个问题。 谢谢! – EZDsIt
@EZDsIt欢迎您! – Eduardo
你还应该检查'null'字段'currentCameraBounds'。 –