android - pin - ¿Cómo sé que el mapa está listo para usarse cuando se usa SupportMapFragment?
pin map android (7)
Con los últimos MapFragment.getMapAsync puedes usar MapFragment.getMapAsync . Directamente de los documentos
Establece un objeto de devolución de llamada que se activará cuando la instancia de GoogleMap esté lista para su uso.
En el método onCreate
, estoy haciendo uso de 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 agregar un marcador. El problema es cuando la llamada a getMap
es nula, ¿cuándo puedo intentar de nuevo? ¿Hay algún evento en el que me pueda registrar o mi enfoque es erróneo?
mMap = ((SupportMapFragment)(getSupportFragmentManager().findFragmentById(R.id.map))).getMap();
if(mMap == null)
//what do I do here?
De hecho, el mapa se muestra en el teléfono, pero parece que no tengo suerte en obtener la referencia para agregar marcadores.
ACTUALIZAR:
La razón por la que estaba creando SupportMapFragment
través del constructor es porque el setContentView
típico se setContentView
y no funcionaba. Esto me puso en la situación en la que no pude obtener mi referencia en el método onCreate
porque de hecho estaba creando el SupportMapFragment
en ese momento. En una investigación posterior, parece que mi problema setContentView
fue un subproducto de no tener tanto el jar de Google-play-services COMO el módulo / src configurado como parte del proyecto en general. Al hacer AMBOS de estos, setContentView
ahora funciona y puedo obtener la referencia a través de getMap()
como era de esperar.
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
}
EDITAR: getMap
está en desuso ahora
El problema es cuando la llamada a getMap es nula, ¿cuándo puedo intentar de nuevo?
Eso depende de la naturaleza del problema.
Si configura 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: el GoogleMap
aún no existe. Puede extender SupportMapFragment
e invalidar onActivityCreated()
, ya que getMap()
está listo para entonces.
Sin embargo, getMap()
también puede devolver null
para un problema mayor, como que no se instalen los Servicios de Google Play. Debería usar algo como GooglePlayServicesUtil.isGooglePlayServicesAvailable()
para detectar esta condición y tratarla como lo desee.
El mes pasado (diciembre de 2014), Google brindó una solución oficial para este problema. En los más recientes (6.5) Servicios de Google Play :
El método getMap () en MapView y MapFragment ahora está en desuso en favor del nuevo método getMapAsync ().
Con getMapAsync(OnMapReadyCallback callback)
puede configurar el escucha para cuando GoogleMap esté listo. Se pasa en devolución de llamada y se proporciona para que no sea nulo.
Google proporcionó un código de muestra 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, se te llamará
@Override
public void onMapReady(GoogleMap map) {
map.addMarker(new MarkerOptions()
.position(new LatLng(0, 0))
.title("Marker"));
}
También puede usar MapsInitializer.initialize(context);
si el problema está relacionado con las bibliotecas que no se han inicializado.
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 usado una interfaz y anular el método onAttach (actividad), pero en mi caso, no quería que la devolución de llamada volviera a mi actividad principal. Quería que volviera a una instancia de Fragment. (El GoogleMap era esencialmente un fragmento dentro de un fragmento) Configuré la devolución de llamada y programáticamente cargué el mapa con esto. Me gustaría haber configurado suMapViewCreatedListener dentro del constructor de MySupportMapFragment, pero se desaconseja usar cualquier cosa que no sea 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, pude obtener el mapa; ¡no más nulo!
public void initPlacesGoogleMapCtrl() {
// Map ready, get it.
GoogleMap googleMap = itsMySupportMapFragment.getMap();
// Do what you want...
}
Yo comentaría sobre la respuesta de CommonsWare pero no tengo suficientes representantes para eso. De todos modos, también tenía 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é SupportMapFragment y luego lo agregué al fragmento a través de childFragmentManager. Mantuve la referencia al SupportMapFragment y esperaba que me diera el mapa en onActivityCreated, que no fue así. La solución a ese problema fue anular el onActivityCreated del SupportMapFragment pero no el fragmento principal. 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;
}
si map == null, busca el mapa
if (mGoogleMap == null)
{
SupportMapFragment mapFragment1 = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
mapFragment1.getMapAsync(this);
}
y luego llama a tu función enMapReady ();