¿Cómo sé que el mapa está listo para utilizarse cuando se utiliza el SupportMapFragment?
En el método onCreate
, estoy utilizando el SupportMapFragment
para mostrar un mapa.
SupportMapFragment fragment = new SupportMapFragment(); getSupportFragmentManager().beginTransaction() .add(android.R.id.content, fragment).commit();
En conjunción con esto, me gustaría añadir un marcador. El problema es cuando la llamada a getMap
es nula, ¿cuándo puedo intentarlo de nuevo? ¿Hay un evento en el que pueda inscribirme o mi enfoque sea erróneo?
- Área de clic del marcador de mapa de Google
- Java.lang.StackOverflowError en com.google.maps.api.android.lib6.gmm6.lla
- Botón My-Location de GoogleMaps v2 Android, no se muestra
- Android Place API: PlaceDetectionApi.getCurrentPlace () siempre devuelve ningún resultado
- Google Maps Android: ajustar la polilínea a la calle
mMap = ((SupportMapFragment)(getSupportFragmentManager().findFragmentById(R.id.map))).getMap(); if(mMap == null) //what do I do here?
El mapa es, de hecho, mostrar en el teléfono sin embargo, parecen no tener suerte en la obtención de la referencia para agregar marcadores.
ACTUALIZAR:
La razón por la que estaba creando el SupportMapFragment
través del constructor es porque el setContentView
típico setContentView
y no funcionaba. Esto me puso en la situación en la que no podía obtener mi referencia en el método onCreate
ya que de hecho estaba creando el SupportMapFragment
en ese momento. En una investigación más setContentView
, parece que mi problema de setContentView
era un subproducto de no tener tanto el jar de Google Play-Services como el módulo / src configurado como parte del proyecto general. Al hacer AMBOS de estos, setContentView
ahora funciona y puedo obtener la referencia a través de getMap()
como yo esperaría.
Lots.xml …
<?xml version="1.0" encoding="utf-8"?> <fragment xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/map" android:name="com.google.android.gms.maps.SupportMapFragment" android:layout_width="match_parent" android:layout_height="match_parent" />
LotsActivity.java …
public class LotsActivity extends FragmentActivity { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.lots); GoogleMap mMap; mMap = ((SupportMapFragment)(getSupportFragmentManager().findFragmentById(R.id.map))).getMap(); if(mMap == null) //this should not occur now }
- Pantalla en blanco de la API de Google Map API V2
- Cómo agregar el logotipo en la pantalla de consentimiento de google?
- "La aplicación no se ejecutará a menos que actualices los servicios de Google Play" con Google Maps API
- Google Maps v2 en el Android Studio. No se encontró GeoPoint
- Android Google Maps no se muestra en firmado apk V2
- google maps api clave no funciona v2
- Hacer TileOverlays transparente
- Problema al eliminar el elemento de clustermanager
EDITAR: getMap
está obsoleto ahora
El problema es cuando la llamada a getMap es nula, ¿cuándo puedo intentarlo de nuevo?
Eso depende de la naturaleza del problema.
Si configura el SupportMapFragment
través del elemento <fragment>
en el diseño, puede llamar a getMap()
éxito en onCreate()
. Pero, si crea el SupportMapFragment
través del constructor, eso es demasiado pronto – GoogleMap
todavía no existe. Puede extender SupportMapFragment
y anular onActivityCreated()
, ya que getMap()
está listo para entonces.
Sin embargo, getMap()
también puede devolver null
para un problema mayor, como Google Play Services no está instalado. Tendrías que usar algo como GooglePlayServicesUtil.isGooglePlayServicesAvailable()
para detectar esta condición y tratar con ella como quieras.
Terminé extendiendo la clase SupportMapFragment y usando una devolución de llamada. El código está aquí:
public class MySupportMapFragment extends SupportMapFragment { public MapViewCreatedListener itsMapViewCreatedListener; // Callback for results public abstract static class MapViewCreatedListener { public abstract void onMapCreated(); } @Override public View onCreateView (LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = super.onCreateView(inflater, container, savedInstanceState); // Notify the view has been created if( itsMapViewCreatedListener != null ) { itsMapViewCreatedListener.onMapCreated(); } return view; } }
Preferiría haber utilizado una interfaz y anular el método onAttach (actividad), pero en mi caso, no quería que la devolución de llamada regresara a mi MainActivity. Quería que volviera a una instancia de Fragmento. (El GoogleMap era esencialmente un fragmento dentro de un fragmento) configuré la devolución de llamada y cargaba el mapa por programa con esto. Me gustaría tener establecido suMapViewCreatedListener dentro del constructor de MySupportMapFragment, pero se desaconseja usar cualquier otra cosa que constructores sin parámetros.
itsMySupportMapFragment = new MySupportMapFragment(); MapViewCreatedListener mapViewCreatedListener = new MapViewCreatedListener() { @Override public void onMapCreated() { initPlacesGoogleMapCtrl(); } }; itsMySupportMapFragment.itsMapViewCreatedListener = mapViewCreatedListener; FragmentTransaction transaction = getActivity().getSupportFragmentManager().beginTransaction(); transaction.replace(R.id.mapFragmentContainer, itsMySupportMapFragment); transaction.addToBackStack(null); transaction.commit();
Y luego, cuando recibí la llamada de vuelta, pude conseguir el mapa; No más nulo
public void initPlacesGoogleMapCtrl() { // Map ready, get it. GoogleMap googleMap = itsMySupportMapFragment.getMap(); // Do what you want... }
Quisiera comentar la respuesta de CommonsWare pero no tengo suficiente representante para eso. De todos modos, también estaba teniendo este problema que getMap () devolvería null en onActivityCreated. Mi configuración es la siguiente: Tengo MainActivity que contiene un fragmento. En el método onCreateView de ese fragmento creé el SupportMapFragment y lo agregué al fragmento vía childFragmentManager. Me mantuve referencia a la SupportMapFragment y esperaba que me diera el mapa en onActivityCreated que no lo hizo. La solución a ese problema era anular el onActivityCreated del SupportMapFragment pero no el fragmento padre. Lo hice así en onCreateView:
@Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View v = inflater.inflate(R.layout.fragment_location, container, false); mMapFragment = new SupportMapFragment() { @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); mMap = mMapFragment.getMap(); if (mMap != null) { setupMap(); } } }; getChildFragmentManager().beginTransaction().add(R.id.framelayout_location_container, mMapFragment).commit(); return v; }
El mes pasado (diciembre de 2014) Google dio la solución oficial para este problema. En los servicios de Google Play más recientes (6.5) :
El método getMap () en MapView y MapFragment ahora está obsoleto a favor del nuevo método getMapAsync ().
Con getMapAsync(OnMapReadyCallback callback)
puede configurar el oyente para cuando GoogleMap esté listo. Se pasa en devolución de llamada y se proporciona para no ser nulo.
Google proporcionó un código de ejemplo para esto:
public class MainActivity extends FragmentActivity implements OnMapReadyCallback { ... }
Y al inicializar el fragmento:
MapFragment mapFragment = (MapFragment) getFragmentManager().findFragmentById(R.id.map); mapFragment.getMapAsync(this);
Cuando el mapa esté listo, la devolución de llamada se llamará
@Override public void onMapReady(GoogleMap map) { map.addMarker(new MarkerOptions() .position(new LatLng(0, 0)) .title("Marker")); }
También puede utilizar MapsInitializer.initialize(context);
Si el problema está relacionado con las bibliotecas que no están siendo inicializadas.
Con los últimos GoogleServices puede utilizar MapFragment.getMapAsync . Directamente desde los documentos
Establece un objeto de devolución de llamada que se activará cuando la instancia de GoogleMap esté lista para utilizarse.
Si mapa == nulo y luego encontrar el mapa
if (mGoogleMap == null) { SupportMapFragment mapFragment1 = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map); mapFragment1.getMapAsync(this); }
Y luego llamar a su función onMapReady ();