2015-06-19 8 views
13

Obecny Android Google Maps API wymaga połączenia mapFragment.getMapAsync z OnMapReadyCallback, zanim będzie można uzyskać dostęp do GoogleMap. Zakładałem, że gdy już raz masz GoogleMap, będzie bezpiecznie zadzwonić pod numer moveCamera(), ale widziałem raporty o awariach z IllegalStateException, które mówiły: Map size can't be 0. Most likely, layout has not yet occured for the map view.Kiedy można wywołać GoogleMap.moveCamera po onMapReady z OnMapReadyCallback?

Tak więc próbowałem dodać ViewTreeObserver.OnPreDrawListener i przenieść wywołanie moveCamera() do metody onPreDraw, jako dokumentację dla tego słowa "W tym momencie wszystkie widoki w drzewie zostały zmierzone i otrzymały ramkę". Ale I nadal zobacz niektóre raporty o awariach z tym samym problemem. Nie mogę znaleźć żadnej dokumentacji na ten temat - są takie pytania, jak moveCamera with CameraUpdateFactory.newLatLngBounds crashes, ale wcześniejszy interfejs API getMapAsync, więc nie są zbyt pomocne.

+0

widzę to też - dziwnie, wydaje się jedynie wpływać na ruchy kamery do 'CameraUpdateFactory.newLatLngBounds (granice wyściółka)', ale nie 'CameraUpdateFactory.newLatLng (długość i szerokość geograficzną) '- więc zakładam, że ma to coś wspólnego z paddingiem. Mogę replikować podczas tworzenia nowej aktywności mapy z szablonu w Android Studio na LG G4 w/Android 5.1. –

Odpowiedz

-1

Możesz zrobić wszystko, co chcesz zaraz po tym, jak otrzymasz onMapReady (GoogleMap googleMap).

ten pracuje teraz w 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)); 
      } 
}); 
+1

Może to działać w ogólnym przypadku, ale próbowałem tego i pojawiły się raporty o awariach. Nie wiem, czy są one powiązane z konkretną wersją Androida lub konkretnego urządzenia, ale na pewno się zdarzą. –

+0

To działa dobrze od API 14 do 21, czy jesteś pewien, że przyczyną jest wyjątek? – Nanoc

+0

Tak, tak, jestem. Jeśli ponownie przeczytasz to pytanie, zobaczysz, że już próbowałem tego, co sugerujesz, ale widziałem awarie. Nie setki wypadków, ale kilka. Z moim zaktualizowanym podejściem widzę jeszcze mniej awarii, ale problem nie został całkowicie rozwiązany. –

0

miałem ten sam problem. Zaadaptowałem rozwiązanie z podanego łącza, które wydaje się działać dla mnie. W onCreate():

rootView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { 
    public void onGlobalLayout() {displayMap();} 
}); 

OnGlobalLayoutListener() wydaje się być wywołana wiele razy w układzie, więc być może bardziej precyzyjnie kierowane słuchacz będzie lepiej. Aby uniknąć nieefektywności manipulowania mapą bardziej niż to konieczne, użyłem boolowskiego 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; 
} 
+0

Cieszę się, że nie jestem jedyną osobą, która widzi problem. Zastanawiam się w twoim rozwiązaniu, czy powinieneś usunąć 'OnGlobalLayoutListener' po pomyślnym zainicjowaniu mapy? –

+0

Dobre pytanie!Prawdopodobnie uzyskamy niewielki wzrost wydajności. Zauważ, że opuszczenie go nie spowoduje dalszych prób konfiguracji mapy z powodu flagi mapInitialised. Podnosi to pytanie o to, co się stanie, jeśli kolejna zmiana układu będzie różnić się wielkością funkcji MapFragment, ale normalna instalacja kanalizacyjna wydaje się z tym w porządku. –

+0

Powinno być bezpieczne usunięcie słuchacza. Po ustawieniu kamery w pierwszej kolejności, niech będzie obsługiwane przez MapView (pamięta lokalizację na ekranie, nawet jeśli użytkownik przesunął mapę w innym miejscu). Na rotacji ekranu z całą pewnością będziesz odtwarzał hierarchię aktywności/widoku, więc i tak będziesz potrzebował nowego słuchacza układu. –

9

miałem ten sam problem. Ta biblioteka map google zgłasza wyjątek, gdy aplikacja próbuje zmienić kamerę za pomocą tej aktualizacji kamery, dopóki mapa nie przejdzie układu (aby ta metoda prawidłowo określała odpowiednie pole ograniczające i poziom powiększenia, mapa musi mieć rozmiar). Opisano here.

To moje rozwiązanie:

@Override 
public void onMapReady(GoogleMap googleMap) { 
    googleMap.setOnMapLoadedCallback(this); 
} 

@Override 
public void onMapLoaded() { 
    googleMap.animateCamera(CameraUpdateFactory.newLatLngBounds(…)); 
} 
+0

Dzięki! To działa dobrze! –

+1

Dokumenty znajdujące się tutaj https://developers.google.com/android/reference/com/google/android/gms/maps/OnMapRerenceCallback jednoznacznie informują, że nie będą łańcuchować zdarzeń. "Nie podłączaj słuchawek OnMapReadyCallback i OnGlobalLayoutListener, ale zamiast tego rejestruj i czekaj na oba wywołania zwrotne niezależnie, ponieważ wywołania zwrotne mogą być uruchamiane w dowolnej kolejności." – m0bl

Powiązane problemy