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.
- Color de fondo de la actividad de la pantalla de bienvenida
- El dispositivo Android BLE se desconecta después de poco tiempo, el código de error 8
- Cómo se utiliza la clase BluetoothA2dp en Xamarin
- Tejido TwitterKit en Xamarin
- Esperando separador de ruta de clase ';' Antes de '\ Android \ android-sdk \ build-tools \ 23.0.1 \ lib \ shrinkedAndroid.jar' en el argumento número 8
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?
- Tablas de la barra de acción de Android, Styling el icono y el texto juntos
- Xamarin-Android Mvvmcross - Tocar en la aplicación de inicio de notificación recibida con salpicaduras o llevar al frente
- "Versión de facturación en la aplicación 3 NO admitida" con Play Store actualizada
- ¿Cómo puedo cancelar desde Device.StartTimer?
- Monodroid - Manejo de eventos en las vistas secundarias de filas ListView reutilizadas
- Xamarin: Error al abrir una sesión para la máquina virtual Nexus 7 (Lollipop)
- Resolución de DNS falla en android
- La pantalla no se mueve correctamente cuando el teclado se mueve hacia arriba - android
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!
- RecyclerView desplazamiento laggy
- ¿Cómo se calcula el tamaño de un widget Android después de la distribución?