Android DialogFragment disparaît après le changement d'orientation

J'ai une classe V4 de support Fragmentativity qui implémente deux fragments côte à côte (un peu comme gmail) et un bouton qui peut faire apparaître un DialogFragment.

Tout cela fonctionne très bien à moins que j'ai un changement d'orientation. Lorsque j'ai un changement d'orientation, les États des Fragments ne sont pas enregistrés.

Et le principal problème est que si J'ai un FragmentDialog ouvert, il disparaît simplement.

J'ai mis setRetainInstance(true); dans tous les fragments mais ce n'est pas le cas aider.

Dans mon manifeste, j'ai inclus android:configChanges="orientation" mais n'aide toujours pas.

Voici mes exemples de code, merci pour l'aide.

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;
        //}
    }
}

Et dans mon activité Principale:

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();
        }
    }
34
demandé sur AlexIIP 2012-09-15 03:57:39

4 réponses

Ok, donc le problème semble être avec la bibliothèque de compatibilité DialogFragment.

Le problème a été décrit dans ce post.

" Un MESSAGE DE REJET obsolète pour le fragment est conservé dans la file d'attente des messages. Il a été mis en file d'attente par DialogFragment.onDestroyView() lors du rejet de l'ancienne boîte de dialogue et est réactivé après la création de la nouvelle boîte de dialogue.

Une solution de contournement rapide (et éventuellement sale) consiste à remplacer onDestroyView() et à effacer l'écouteur de rejet avant d'appeler super.onDestroyView() "

Ajouter le code suivant pour mon DialogFragment résolu le problème:

 @Override
 public void onDestroyView() {
     if (getDialog() != null && getRetainInstance()) {
         getDialog().setDismissMessage(null);
     }
     super.onDestroyView();
 }
72
répondu AlexIIP 2015-03-05 09:25:56

Dans l'intérêt de la pauvre âme (moi) qui a le même problème pour des raisons différentes, je vais poster ceci. Le fragment de dialogue doit être conservé automatiquement tant que vous procédez comme suit:

  1. Si vous appelez un Activity onSaveInstanceState(), assurez-vous que vous appelez la fonction super!!!!. Dans mon cas, cela a été la clé. Assurez-vous également de faire la même chose dans le Fragment.
  2. Si vous utilisez setRetainInstance, vous devrez stocker manuellement les valeurs et les appliquer à nouveau. Sinon, vous devriez être capable de ne pas s'inquiéter à ce sujet, dans la plupart des cas. Si vous faites quelque chose d'un peu plus compliqué, vous devrez peut-être setRetainInstance(true), mais sinon l'ignorer. Dans mon cas, je devais l'utiliser pour stocker une graine aléatoire pour l'une de mes classes, mais sinon j'allais bien.
  3. certaines personnes se sont plaintes d'un bug dans la bibliothèque de support, où un message de rejet est envoyé alors qu'il ne devrait pas l'être. La dernière bibliothèque de support semble avoir corrigé cela, donc vous ne devriez pas avoir à vous inquiéter à ce sujet.

Vous ne devrait pas avoir besoin de faire quelque chose de fantaisie comme stocker manuellement le fragment, cela devrait être fait automatiquement si vous suivez ces étapes. Dans l'ensemble, cela semble faire l'affaire pour toute personne ayant une bibliothèque de support plus moderne.

13
répondu PearsonArtPhoto 2014-02-22 16:09:41

Dans mon cas, J'avais un DialogFragment montrant un autre DialogFragment en utilisant

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

Le changer en

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

Correction du problème

2
répondu Maragues 2014-11-25 17:32:05

En plus de définir setRetainInstance(true);, Placez simplement le code suivant dans votre DialogFragment. C'est une solution testée.

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);
    }
}
1
répondu Azmat Ali Khan 2014-04-25 19:07:08