it-swarm.com.de

Android DialogFragment verschwindet nach Änderung der Orientierung

Ich habe eine FragmentActivity-Support-Klasse v4, die zwei nebeneinander liegende Fragmente (wie gmail) und eine Schaltfläche implementiert, mit der ein DialogFragment aufgerufen werden kann. 

Das funktioniert alles super, wenn ich keine Orientierungsänderung habe. Wenn ich eine Orientierungsänderung habe, werden die Zustände der Fragmente nicht gespeichert.

Und das Hauptproblem ist, wenn ich den FragmentDialog geöffnet habe, verschwindet er einfach.  

Ich habe setRetainInstance(true); in alle Fragmente gesetzt, aber es hat nicht geholfen.

In meinem Manifest habe ich Android:configChanges="orientation" aufgenommen, hilft aber trotzdem nicht.

Hier sind meine Codebeispiele, vielen Dank für die Hilfe.

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

und in meiner Haupttätigkeit:

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();
        }
    }
35
AlexIIP

Okay, das Problem scheint die DialogFragment-Kompatibilitätsbibliothek zu sein. 

Das Problem wurde in this post beschrieben.

"Eine veraltete DISMISS-Nachricht für das Fragment wird in der Nachrichtenwarteschlange beibehalten. Sie wurde von DialogFragment.onDestroyView() in eine Warteschlange gestellt, als der alte Dialog geschlossen wurde, und wird nach dem Erstellen des neuen Dialogs wieder aktiviert.

Eine schnelle (und möglicherweise schmutzige) Problemumgehung besteht darin, onDestroyView() zu überschreiben und den Listener zu löschen, bevor super.onDestroyView() aufgerufen wird. "

Durch das Hinzufügen des folgenden Codes zu meinem DialogFragment wurde das Problem behoben:

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

Im Interesse der armen Seele (Ich), die aus verschiedenen Gründen das gleiche Problem hat, werde ich dies posten. Das Dialogfragment sollte automatisch beibehalten werden, solange Sie Folgendes tun:

  1. Wenn Sie eine Activity onSaveInstanceState() aufrufen, stellen Sie sicher, dass Sie die Superfunktion !!!! aufrufen. In meinem Fall war das der Schlüssel. Stellen Sie außerdem sicher, dass Sie im Fragment dasselbe tun.
  2. Wenn Sie setRetainInstance verwenden, müssen Sie die Werte manuell speichern und erneut anwenden. Ansonsten sollten Sie sich in den meisten Fällen keine Sorgen machen müssen. Wenn Sie etwas komplizierter machen, müssen Sie möglicherweise setRetainInstance(true), aber ansonsten ignorieren. In meinem Fall musste ich es verwenden, um einen zufälligen Samen für eine meiner Klassen zu speichern, aber ansonsten war ich okay.
  3. Einige Leute haben sich über einen Fehler in der Support-Bibliothek beschwert, bei dem eine Ablehnungsnachricht gesendet wird, wenn dies nicht der Fall sein sollte. Die neueste Support-Bibliothek scheint das behoben zu haben, sodass Sie sich keine Sorgen machen müssen.

Sie sollten nichts weiter tun müssen, als das Fragment manuell zu speichern. Dies sollte automatisch geschehen, wenn Sie die folgenden Schritte ausführen. Insgesamt scheint dies für alle, die über eine modernere Unterstützungsbibliothek verfügen, den Trick.

13
PearsonArtPhoto

In meinem Fall hatte ich ein DialogFragment mit einem anderen DialogFragment

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

Ändern Sie es zu

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

das Problem behoben

2
Maragues

Zusätzlich zur Einstellung von setRetainInstance(true); fügen Sie einfach den folgenden Code in Ihre DialogFragment ein. Es ist eine getestete Lösung.

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
Azmat Ali Khan