Cómo preservar / volver a enlazar a los oyentes de eventos en MapFragment después de girar el dispositivo (retrato / paisaje)?

Estoy desarrollando una aplicación para Android con Xamarin (versión 7.1). Se muestra como mapa y dibuja PolyLines, haciéndolo en OnCameraIdle() .

El MapFragment se genera mediante programación en OnCreate . Estoy buscando el GoogleMap en OnResume través de GetMapAsync y la vinculación de los oyentes en OnMapReady .
Funcionan bien, pero sólo en el principio. Tan pronto como se gira el dispositivo (retrato -> paisaje O viceversa), el movimiento de la cámara no activa más a los oyentes.
El mapa funciona, sin embargo – yo (el usuario) todavía puede mover la cámara muy bien. Yo (la aplicación) simplemente no puede trabajar con él más.

Este es el código desnudo, sólo la creación y manejo del mapa. Todo lo demás (dibujo real) se elimina:

 public class MapActivity : Activity, IOnMapReadyCallback, GoogleMap.IOnCameraIdleListener, GoogleMap.IOnCameraMoveStartedListener { private GoogleMap _map; private MapFragment _mapFragment; private void InitializeMap() { _mapFragment = MapFragment.NewInstance(); var tx = FragmentManager.BeginTransaction(); tx.Add(Resource.Id.map_placeholder, _mapFragment); tx.Commit(); } private void SetMapListeners() { Log.Debug("MyApp/ Map", "SetMapListeners"); _map.SetOnCameraIdleListener(this); _map.SetOnCameraMoveStartedListener(this); } /* Activity */ protected override void OnCreate(Bundle savedInstanceState) { base.OnCreate(savedInstanceState); Log.Debug("MyApp / Map", "OnCreate"); SetContentView(Resource.Layout.Map); InitializeMap(); } protected override void OnStart() { base.OnStart(); Log.Debug("MyApp / Map", "OnStart"); } protected override void OnResume() { base.OnResume(); if (_map == null) _mapFragment.GetMapAsync(this); Log.Debug("MyApp / Map", "OnResume"); } protected override void OnPause() { base.OnPause(); Log.Debug("MyApp / Map", "OnPause"); } protected override void OnStop() { base.OnStop(); Log.Debug("MyApp / Map", "OnStop"); } protected override void OnDestroy() { base.OnStop(); Log.Debug("MyApp/ Map", "OnDestroy"); } /* IOnMapReadyCallback */ public void OnMapReady(GoogleMap googleMap) { Log.Debug("MyApp / Map", "Map is ready!"); _map = googleMap; SetMapListeners(); } /* IOnCameraIdleListener */ public void OnCameraIdle() { Log.Debug("MyApp / Map", "Camera is idle."); // Drawing routine is called here } /* IOnCameraMoveStartedListener */ public void OnCameraMoveStarted(int reason) { Log.Debug("MyApp / Map", "Camera move started."); } } 

Como se puede ver en el siguiente extracto de registro, los oyentes funcionan al principio, pero una vez que el dispositivo se rota (al menos) una vez, se han ido.
También intenté llamar a SetMapListeners sólo una vez en el ciclo de vida, la primera vez que se llama OnMapReady , pero eso no cambió nada.

 04-03 20:29:06.486 D/MyApp / Map( 7446): OnCreate 04-03 20:29:06.688 I/Google Maps Android API( 7446): Google Play services client version: 10084000 04-03 20:29:06.695 I/Google Maps Android API( 7446): Google Play services package version: 10298438 04-03 20:29:07.394 D/MyApp / Map( 7446): OnStart 04-03 20:29:07.399 D/MyApp / Map( 7446): OnResume 04-03 20:29:07.432 D/MyApp / Map( 7446): Map is ready! 04-03 20:29:07.438 D/MyApp / Map( 7446): SetMapListeners 04-03 20:29:07.568 D/MyApp / Map( 7446): Camera is idle. 04-03 20:29:09.231 D/MyApp / Map( 7446): Camera move started. 04-03 20:29:09.590 D/MyApp / Map( 7446): Camera is idle. 04-03 20:29:12.350 D/MyApp / Map( 7446): Camera move started. 04-03 20:29:12.751 D/MyApp / Map( 7446): Camera is idle. ## Listeners are responding, now rotating the device. 04-03 20:29:15.503 D/MyApp / Map( 7446): OnPause 04-03 20:29:15.508 D/MyApp / Map( 7446): OnStop 04-03 20:29:15.572 D/MyApp / Map( 7446): OnDestroy 04-03 20:29:15.595 I/Google Maps Android API( 7446): Google Play services package version: 10298438 04-03 20:29:15.596 D/MyApp / Map( 7446): OnCreate 04-03 20:29:15.628 I/Google Maps Android API( 7446): Google Play services package version: 10298438 04-03 20:29:15.655 D/MyApp / Map( 7446): OnStart 04-03 20:29:15.655 D/MyApp / Map( 7446): OnResume 04-03 20:29:15.690 D/MyApp / Map( 7446): Map is ready! 04-03 20:29:15.691 D/MyApp / Map( 7446): SetMapListeners ## Map is rotated, camera position was preserved. ## Now moving the camera, but no listeners are responding. 04-03 20:29:24.436 D/MyApp / Map( 7446): OnPause 04-03 20:29:31.288 D/MyApp / Map( 7446): OnStop 04-03 20:29:31.359 D/MyApp / Map( 7446): OnDestroy 

Lo interesante aquí para mí es que cuando vuelvo a la actividad anterior y abrir el mapa una vez más, comienza de nuevo y funciona de nuevo. Sin embargo, como se ve en el registro, al girar el dispositivo, la actividad también se destruye y recién creada. Por lo que sé, el fragmento no es, así que tal vez eso es una pista. No lo sé.

También intenté quitar a los oyentes en OnDestroy (fijando el null ), pero eso, también, no cambió nada.

¿Tienes idea de lo que podría estar haciendo mal?

Trate de comprobar savedInstanceState para ver si su actividad se está construyendo por primera vez o si es sólo una vuelta a ella. Usted parece estar superponiendo fragmentos en cada llamada.

Intente poner la llamada InitializeMap () en la anulación del método OnCreateView () en lugar de OnCreate ()

De forma predeterminada, cuando se gira la pantalla, se cancela la actividad y se reinicia. Para asegurarse de que no se pierden datos, es necesario guardar y restaurar correctamente los datos utilizando los métodos del ciclo de vida. Vea SavingPersistentState y Siga esta documentación para desarrolladores de Android Hope This May helps.!

Tuve problemas similares, porque tenemos el MapFragment anidados dentro de otro Fragmento, por lo que tenemos que volver a agregar el MapFragment cada vez. Puesto que usted lo tiene encajado directamente en una actividad, el paquete del @App también debe trabajar, pero pegaré el código de todos modos.

 @Override protected void onAttachedToWindow() { super.onAttachedToWindow(); //onCreateView() or onResume() should work too FragmentManager fragmentManager = ((AppCompatActivity) getContext()).getSupportFragmentManager(); SupportMapFragment mapFragment = SupportMapFragment.newInstance(); fragmentManager.beginTransaction() .replace(R.id.mapContainer, mapFragment) .commit(); mapFragment.getMapAsync(this); } @Override public void onMapReady(GoogleMap googleMap) { this.googleMap = googleMap; UiSettings uiSettings = googleMap.getUiSettings(); uiSettings.setZoomControlsEnabled(false); //do your initialization + recreate your last map position from BundleSavedIntance: check this answer: http://stackoverflow.com/questions/16697891/google-maps-android-api-v2-restoring-map-state/16698624#16698624 } 

Y por favor: las funciones deben comenzar en minúsculas!

  • Cómo persistir Button.Pressed estado en Xamarin.Android?
  • HttpClient.GetAsync nunca vuelve en Xamarin.Android
  • Combine Xamarin y React Native en una aplicación
  • Xamarin, Android. Cada vez que ejecute la aplicación en el dispositivo, la aplicación se unistalled y luego se instala de nuevo.
  • Establecer LinearLayout color de fondo a través de valor booleano
  • Mostrar iconos en las fichas FragmentPagerAdapter
  • Xamarin C # - Android - Impedir que un AlertDialog cierre en PositiveButton haga clic
  • Java.IO.ISerializable Xamarin
  • ¿Alguien tiene puntos de referencia (código y resultados) que comparan el rendimiento de las aplicaciones de Android escritas en Xamarin C # y Java?
  • Las pestañas de Android en fragmento con barra de herramientas de contracción
  • El botón Atrás de la barra de herramientas no funciona
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.