Cập nhật kể từ tháng 8 năm 2016
Tóm tắt các đúng câu trả lời ngay bây giờ cho vấn đề này là sử dụng mới onCameraIdle
, thay vì OnCameraChangeListener
, mà bây giờ deprecated. Đọc dưới đây làm thế nào.
Giờ đây, bạn có thể nghe "dragEnd" giống như sự kiện và thậm chí cả các sự kiện khác trên phiên bản Google Maps dành cho Android mới nhất.
Như được hiển thị trong docs, bạn có thể tránh sự cố nhiều cuộc gọi (một số ") của số OnCameraChangeListener
bằng cách sử dụng trình nghe mới. Ví dụ: bạn hiện có thể kiểm tra lý do đằng sau sự di chuyển của camera là lý tưởng để ghép nối với sự cố fetchData
theo yêu cầu. Mã sau đây chủ yếu được lấy trực tiếp từ tài liệu. Một điều nữa, nó là cần thiết để sử dụng Google Play Services 9.4.
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)
}
}
Giải pháp cho một giải pháp hiệu quả trước tháng 8 năm 2016
Như câu hỏi được trả lời đúng, tôi muốn thêm vào đó một khả năng là vấn đề tiếp theo.
Sự cố phát sinh khi sử dụng OnCameraChangeListener
để tìm nạp dữ liệu từ máy chủ do tần suất mà phương pháp này được kích hoạt.
Có một issue báo cáo về cách điên cuồng thường xuyên phương pháp này được trigged khi thực hiện một bản đồ đơn giản trượt, do đó trong ví dụ của câu hỏi, nó sẽ kích hoạt fetchData
nhiều lần liên tục thay đổi camera rất ít, thậm chí không có thay đổi camera , có, nó xảy ra rằng giới hạn máy ảnh đã không thay đổi, nhưng phương pháp được kích hoạt.
Điều này có thể ảnh hưởng đến hiệu suất bên máy chủ và sẽ lãng phí nhiều tài nguyên của thiết bị bằng cách tìm nạp dữ liệu tuần tự từ máy chủ.
Bạn có thể tìm thấy giải pháp liên kết đó cho vấn đề này, nhưng vẫn chưa có cách chính thức để thực hiện, ví dụ: sử dụng số gọi lại dragEnd
hoặc cameraChangeEnd
mong muốn.
Một ví dụ dưới đây, dựa trên những điều từ đó, là cách tôi tránh được vấn đề nói trên bằng cách chơi với khoảng thời gian của cuộc gọi và loại bỏ các cuộc gọi có cùng ranh giới.
// 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;
}
Rất tốt! Điều đó có thể giúp tôi tiết kiệm nhiều giờ làm việc và sau đó giải quyết vấn đề này. Cảm ơn! – EZDsIt
@EZDsIt bạn được chào đón! – Eduardo
Bạn cũng nên kiểm tra 'null' cho trường' currentCameraBounds'. –