33

Tengo una clase de v2 FragmentActivity support que implementa dos fragmentos uno al lado del otro (tipo de como gmail) y un botón que puede mostrar un DialogFragment.Android DialogFragment desaparece después del cambio de orientación

Todo esto funciona muy bien a menos que tenga un cambio de orientación. Cuando cambio de orientación, los estados de los Fragmentos no se guardan.

Y el problema principal es que si tengo un FragmentDialog abierto, simplemente desaparece.

He configurado setRetainInstance(true); en todos los fragmentos, pero no sirvió de nada.

En mi manifiesto incluí android:configChanges="orientation" pero todavía no ayuda.

Aquí están mis ejemplos de código, gracias por la ayuda.

public class AddMasterDialog extends DialogFragment { 

    private int mTitle; 
    private int mPrompt; 
    private OnClickListener onSaveListener; 
    private OnClickListener onCancelListener; 

    public AddMasterDialog newInstance(int title, int prompt) { 
     AddMasterDialog simpleDialog = new AddMasterDialog(title, prompt); 
     return simpleDialog; 
    } 

    public AddMasterDialog() { 
     // Empty constructor required for DialogFragment 
    } 
    public AddMasterDialog(int title, int prompt) { 
     // Empty constructor required for DialogFragment 
     mTitle = title; 
     mPrompt = prompt; 
    } 
    public void setSaveButton(OnClickListener save){ 
     onSaveListener = save; 
    } 
    public void setCancelButton(OnClickListener cancel){ 
     onCancelListener = cancel; 
    } 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setRetainInstance(true); 
    } 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
      Bundle savedInstanceState) { 

     //if(savedInstanceState == null){ 
      View view = inflater.inflate(R.layout.add_new_simple, container); 
      getDialog().setTitle(mTitle); 
      ((TextView) view.findViewById(R.id.add_simple_new_value_prompt)).setText(mPrompt); 

      Button saveButton = (Button) view.findViewById(R.id.add_simple_save_button); 
      saveButton.setOnClickListener(onSaveListener); 

      //Cancel Button 
      Button cancelButton = (Button) view.findViewById(R.id.add_simple_cancel_button); 
      cancelButton.setOnClickListener(onCancelListener); 
      return view; 
     //} 
    } 
} 

y en mi actividad principal:

private void initiateAddMasterPopupWindow() { 
     try { 
      addMasterDialog = new AddMasterDialog(R.string.add_new_master_dialog_title, R.string.add_master_new_value_prompt); 
      addMasterDialog.setSaveButton(saveNewMasterClickListener); 
      addMasterDialog.setCancelButton(cancelNewMasterClickListener); 
      FragmentManager fm = getSupportFragmentManager(); 
      addMasterDialog.show(fm, ADD_NEW_MASTER); 

     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 

Respuesta

70

bien, así que el problema parece estar relacionado con la biblioteca DialogFragment compatibilidad.

El problema se describió en this publicación.

"Un mensaje DESESTIMAR obsoletos para el fragmento se retiene en la cola de mensajes. Se ha puesto en cola DialogFragment.onDestroyView() al despedir el cuadro de diálogo de edad y se reactiva después de crear el nuevo cuadro de diálogo.

Una solución rápida (y posiblemente sucia) es para anular onDestroyView() y despejar el oyente despedir antes de llamar super.onDestroyView() "

añadiendo el siguiente código a mi DialogFragment resuelto el problema:

@Override 
public void onDestroyView() { 
    if (getDialog() != null && getRetainInstance()) { 
     getDialog().setDismissMessage(null); 
    } 
    super.onDestroyView(); 
} 
+3

solución fresca, funciona muy bien. –

13

En interés del pobre alma (Me) que tiene el mismo problema por diferentes razones, voy a publicar esto. El fragmento de diálogo debe ser preservado de forma automática, siempre y cuando hace lo siguiente:

  1. Si llama a una Activity onSaveInstanceState(), asegúrese de llamar a la función SUPER !!!!. En mi caso, esa fue la clave. También asegúrate de hacer lo mismo en el Fragmento.
  2. Si usa setRetainInstance, deberá almacenar manualmente los valores y volverlos a aplicar. De lo contrario, no debería preocuparse por ello, en la mayoría de los casos. Si está haciendo algo un poco más complicado, puede necesitar setRetainInstance(true), pero de lo contrario ignórelo. En mi caso, necesitaba usarlo para almacenar una semilla aleatoria para una de mis clases, pero de lo contrario estaba bien.
  3. Algunas personas se han quejado de un error en la biblioteca de soporte, donde se envía un mensaje de rechazo cuando no debería. La última biblioteca de soporte parece haber solucionado eso, por lo que no debería preocuparse por eso.

No debe necesitar hacer nada especial como almacenar manualmente el fragmento, debe hacerse automáticamente si sigue estos pasos. En general, esto parece ser el truco para cualquiera con una biblioteca de soporte más moderna.

+4

Gracias por el paso 1 – IHeartAndroid

1

Además de establecer setRetainInstance(true); simplemente coloque el siguiente código en su DialogFragment. Es una solución probada.

private boolean isDismissible = false; 

@Override 
public void dismiss() { 

    try { 

     isDismissible = true; 
     super.dismiss(); 

     Log.d(getClass().getSimpleName(), "Dialog dismissed!"); 

    } catch (IllegalStateException ilse) { 
    } 
} 

@Override 
public void onDismiss(DialogInterface dialog) { 

    // So that dialog should not dismiss on orientation change 
    if (isDismissible) { 

     // So that dialog can be dismissed 
     super.onDismiss(dialog); 
    } 
} 
+0

Crea un diálogo múltiple sobre el cambio de orientación. –

2

En mi caso, tuve una DialogFragment muestra otra DialogFragment usando

listDialogFragment.show(getChildFragmentManager(), "TAG"); 

Si lo cambia a

listDialogFragment.show(getActivity().getSupportFragmentManager(), "TAG"); 

fija el tema

+0

Nota: su cambio es exactamente lo mismo que llamar 'listDialogFragment.show (getFragmentManager()," TAG ");' – William

Cuestiones relacionadas