Когда вы можете позвонить в GoogleMap.moveCamera после onMapReady из OnMapReadyCallback?
В текущем API Google Maps для Google вы должны позвонить mapFragment.getMapAsync
с помощью OnMapReadyCallback
, прежде чем вы сможете получить доступ к GoogleMap
. Я предположил, что если у вас есть GoogleMap
, тогда было бы безопасно вызвать moveCamera()
, но я видел отчеты о сбоях с IllegalStateException
, который сказал Map size can't be 0. Most likely, layout has not yet occured for the map view
.
Итак, я попробовал добавить ViewTreeObserver.OnPreDrawListener
и переместить вызов moveCamera()
на метод onPreDraw
, так как документы для этого говорят "В этот момент все представления в дереве были измерены и заданы рамкой", Но я все еще вижу некоторые отчеты о сбоях с той же проблемой. Я не могу найти документацию для этого - есть вопросы, такие как moveCamera с CameraUpdateFactory.newLatLngBounds сбой, но они предписывают API getMapAsync
, поэтому их не так много помощь.
Ответы
Ответ 1
У меня была такая же проблема. Эта библиотека Google Maps отображает исключение, когда приложение пытается изменить камеру с обновлением этой камеры, пока карта не претерпела макет (чтобы этот метод правильно определял соответствующий ограничивающий прямоугольник и уровень масштабирования, карта должна иметь размер). Здесь описано здесь.
Это мое решение:
@Override
public void onMapReady(GoogleMap googleMap) {
googleMap.setOnMapLoadedCallback(this);
}
@Override
public void onMapLoaded() {
googleMap.animateCamera(CameraUpdateFactory.newLatLngBounds(…));
}
Ответ 2
У меня была та же проблема. Я адаптировал решение из предоставленной вами ссылки, которая, похоже, работает на меня. В onCreate():
rootView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
public void onGlobalLayout() {displayMap();}
});
OnGlobalLayoutListener(), по-видимому, вызывается несколько раз для каждого макета, поэтому, возможно, более точно назначенный слушатель будет лучше. Чтобы избежать неэффективности манипулирования картой больше, чем необходимо, я использовал булевский mMapInitialised.
onMapReady():
@Override public void onMapReady(GoogleMap map) {
mMap = map;
displayMap(); // if width of MapFragment is known
}
displayMap():
void displayMap() {
// Check that mMap has been initialised AND the width of the MapFragment has been set:
if (mMapInitialised || mMap==null) return;
if (mMapFragment.getView().getRight() <= 0) return;
LatLngBounds bounds = new LatLngBounds(new LatLng(mLat_min,mLng_min), new LatLng(mLat_max,mLng_max));
CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngBounds(bounds, 10);
mMap.moveCamera(cameraUpdate);
mMapInitialised = true;
}
Ответ 3
Вы можете делать все, что захотите, сразу после вызова onMapReady (GoogleMap googleMap).
Это работает прямо сейчас в mi app:
mapFragment.getMapAsync(new OnMapReadyCallback() {
@Override
public void onMapReady(GoogleMap googleMap) {
map = googleMap;
map.animateCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(usr.getLatitud(), usr.getLongitud()), 14.6f));
}
});