El fragmento de diálogo omitido vuelve a aparecer cuando se reanuda la aplicación

Hola Estoy desarrollando una aplicación que utiliza mapas.

Estoy utilizando Fragmento Actividad y un fragmento llamado Fragmento-A.

En Fragmento-A hay un botón, al hacer clic en ese botón aparece un fragmento de diálogo, muestra un mapa con alguna ubicación recibida previamente desde el servidor.

Digamos que este fragmento de diálogo es DialogFragment-B.

Tiene un botón para cerrar, un botón para navegar a Google Maps app para obtener direcciones.

Si el usuario navega a DialogFragment-B y regresa al Fragmento-A, al hacer clic en Cerrar botón, todo funciona bien.

Pero si el usuario hace clic en el botón Atrás, el fragmento de diálogo existente se cerrará normalmente y la aplicación funcionará normalmente.

Pero si el usuario pulsó el botón de inicio o recibió una llamada telefónica y onResume se llama a pesar de que el DialogFragment-B se descarta antes, vuelve a aparecer y al cerrar cerrar la aplicación con una excepción de puntero nulo

Aquí está mi código para abrir el DialogFragment-B.

FragmentManager fm = getFragmentManager(); FragmentTransaction ft = fm.beginTransaction(); android.app.Fragment prev = fm.findFragmentByTag(MY_MAP); if (prev != null) { ft.remove(prev); } MyMapFragmentDialog newFragment = MyMapFragmentDialog .newInstance(eachPost); newFragment.show(ft, MY_MAP); 

En DialogFragment-B al hacer clic en botón Cerrar, llamo MyMapFragmentDialog.this.dismiss ();

Por favor, si alguien ha encontrado este problema y superado, guíame a través.

Tuve el mismo problema y se resolvió asegurándome de llamar a super.onDismiss(dialog) en el método onDismiss de mi subclase DialogFragment .

Actualización: La respuesta de Kalina es una solución más elegante y simple – como lo descubrí más tarde!

Estoy enfrentando el mismo problema en una de mis aplicaciones, y no encontrar la respuesta en ninguna parte, pasé por el código fuente de la clase DialogFragment, que está disponible en:

http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.0.1_r1/android/app/DialogFragment.java#DialogFragment.onDismiss%28android.content.DialogInterface% 29

Y allí, encontré la razón probable escrita en un comentario, dentro de la fuente del método onDismiss (diálogo DialogInterface):

 // Note: we need to use allowStateLoss, because the dialog // dispatches this asynchronously so we can receive the call // after the activity is paused. Worst case, when the user comes // back to the activity they see the dialog again. 

Lo que entendí de esto es que el despido no se guarda en el estado de la instancia, y cuando la actividad se reanuda, lo vuelve a mostrar de inmediato como parte de la restauración del estado de la instancia – suponiendo que el fragmento nunca fue descartado. Siendo un evento asincrónico, no hay forma segura de cometer el despido sin arriesgar un

 java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState 

Excepción y accidente consecuente, que es probablemente por qué los autores de la clase optaron por hacerlo de esta manera.

La solución que funcionó para mí era monitorear por separado el estado del DialogFragment, por:

  • Almacenarla en una variable de clase (denominada aquí "diálogo")
  • Anulación del método onDismiss (diálogo DialogInterface) y
  • Establecimiento de un booleano dialogDismissed flag to true

 @Override public void onDismiss(DialogInterface dialog) { // dialogDismissed is a Class level variable in the containing Activity, // must be set to false each time the DialogFragment is shown dialogDismissed = true; } 
  • Nota: si el DialogFragment es una clase separada, entonces un método en la actividad tendrá que ser llamado desde el onDismiss para hacer esto, tal vez mediante la creación de una interfaz

  • Esta bandera debe entonces ser comprobada en la actividad onResume () y un dismiss forzado (después de comprobar que el diálogo no es nulo):

 @Override public void onResume() { super.onResume(); //... if (dialogDismissed && dialog != null) { dialog.dismiss(); } } 
  • Ver reutilización en fragmentos android
  • Mejores prácticas de fragmentos
  • ¿Es este un uso correcto de Android Fragments y NavigationDrawer?
  • ViewPager con Fragmentos que contienen TableLayouts se carga lentamente:
  • Android cómo detener la actualización Fragmentos en el cambio de ficha
  • Android: ¿cómo notificar la actividad cuando las vistas de Fragmentos están listas?
  • El fragmento de niño desencadena onClick del padre
  • Snackbar no se mueve FAB que colocó dentro de Fragmento
  • ¿Por qué usar Fragmentos?
  • La aplicación se bloquea después de agregar el fragmento
  • Android añadiendo Fragmento dentro de Fragmento
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.