Frage Verhindern Sie die Deaktivierung des Dialogs bei der Bildschirmdrehung in Android


Ich versuche zu verhindern, dass Dialoge, die mit dem Alert-Builder erstellt wurden, beim Neustart der Aktivität geschlossen werden.

Wenn ich die onConfigurationChanged-Methode überladen kann ich dies erfolgreich tun und das Layout auf die richtige Ausrichtung zurücksetzen, aber ich verliere Sticky Text Feature von Editiertext. Um das Dialogproblem zu lösen, habe ich dieses Edittext-Problem erstellt.

Wenn ich die Zeichenketten aus dem editiertext speichere und sie in der onC-Änderungsänderung neu zuweise, scheinen sie immer noch auf den Anfangswert voreinzustellen, nicht auf den, der vor der Drehung eingegeben wurde. Auch wenn ich eine Ungültigmachung erzwinge scheint sie zu aktualisieren.

Ich muss wirklich entweder das Dialogproblem oder das Edittext-Problem lösen.

Danke für die Hilfe.


75
2017-09-26 15:14


Ursprung


Antworten:


Der beste Weg, dieses Problem heutzutage zu vermeiden, ist die Verwendung eines DialogFragment.

Erstellen Sie eine neue Klasse, die erweitert wird DialogFragment. Überschreiben onCreateDialog und gib dein altes zurück Dialog oder AlertDialog.

Dann kannst du es mit zeigen DialogFragment.show(fragmentManager, tag).

Hier ist ein Beispiel mit einem Listener:

public class MyDialogFragment extends DialogFragment {

    public interface YesNoListener {
        void onYes();

        void onNo();
    }

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        if (!(activity instanceof YesNoListener)) {
            throw new ClassCastException(activity.toString() + " must implement YesNoListener");
        }
    }

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        return new AlertDialog.Builder(getActivity())
                .setTitle(R.string.dialog_my_title)
                .setMessage(R.string.dialog_my_message)
                .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {

                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        ((YesNoListener) getActivity()).onYes();
                    }
                })
                .setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() {

                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        ((YesNoListener) getActivity()).onNo();
                    }
                })
                .create();
    }
}

Und in der Aktivität, die Sie anrufen:

new MyDialogFragment().show(getSupportFragmentManager(), "tag"); // or getFragmentManager() in API 11+

Diese Antwort hilft Ihnen, diese anderen drei Fragen (und ihre Antworten) zu erklären:


115
2018-03-31 13:19



// Prevent dialog dismiss when orientation changes
private static void doKeepDialog(Dialog dialog){
    WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
    lp.copyFrom(dialog.getWindow().getAttributes());
    lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
    lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
    dialog.getWindow().setAttributes(lp);
}
public static void doLogout(final Context context){     
        final AlertDialog dialog = new AlertDialog.Builder(context)
        .setIcon(android.R.drawable.ic_dialog_alert)
        .setTitle(R.string.titlelogout)
        .setMessage(R.string.logoutconfirm)
        .setPositiveButton("Yes", new DialogInterface.OnClickListener()
        {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                ...   
            }

        })
        .setNegativeButton("No", null)      
        .show();    

        doKeepDialog(dialog);
    }

40
2017-12-05 07:51



Wenn Sie das Layout bei Orientierungsänderung ändern, würde ich nicht setzen android:configChanges="orientation" in Ihrem Manifest, weil Sie die Ansichten trotzdem neu erstellen.

Speichern Sie den aktuellen Status Ihrer Aktivität (wie eingegebener Text, angezeigter Dialog, angezeigte Daten usw.) mit diesen Methoden:

@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
}

@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
    super.onRestoreInstanceState(savedInstanceState);
}

Auf diese Weise wird die Aktivität onCreate erneut durchlaufen und anschließend die onRestoreInstanceState-Methode aufgerufen, in der Sie den EditText-Wert erneut festlegen können.

Wenn Sie komplexere Objekte speichern möchten, die Sie verwenden können

@Override
public Object onRetainNonConfigurationInstance() {
}

Hier können Sie jedes Objekt speichern und in onCreate müssen Sie nur anrufen getLastNonConfigurationInstance(); um das Objekt zu bekommen.


5
2017-09-26 16:45



Fügen Sie einfach android: configChanges = "orientation" mit Ihrer Aktivität hinzu  Element in AndroidManifest.xml

Beispiel:

<activity
            android:name=".YourActivity"
            android:configChanges="orientation"
            android:label="@string/app_name"></activity>

2
2018-06-27 05:43



Diese Frage wurde vor langer Zeit beantwortet.

Aber das ist es Nicht-Hacky und einfach Lösung, die ich für mich selbst nutze.

Ich tat diese Helferklasse für mich selbst, also können Sie es auch in Ihrer Anwendung verwenden.

Verwendung ist:

PersistentDialogFragment.newInstance(
        getBaseContext(),
        RC_REQUEST_CODE,
        R.string.message_text,
        R.string.positive_btn_text,
        R.string.negative_btn_text)
        .show(getSupportFragmentManager(), PersistentDialogFragment.TAG);

Oder

 PersistentDialogFragment.newInstance(
        getBaseContext(),
        RC_EXPLAIN_LOCATION,
        "Dialog title", 
        "Dialog Message", 
        "Positive Button", 
        "Negative Button", 
        false)
    .show(getSupportFragmentManager(), PersistentDialogFragment.TAG);





public class ExampleActivity extends Activity implements PersistentDialogListener{

        @Override
        void onDialogPositiveClicked(int requestCode) {
                switch(requestCode) {
                  case RC_REQUEST_CODE:
                  break;
                }
        }

        @Override
        void onDialogNegativeClicked(int requestCode) {
                switch(requestCode) {
                  case RC_REQUEST_CODE:
                  break;
                }          
        }
}

2
2018-06-23 13:00



Ein sehr einfacher Ansatz besteht darin, die Dialoge aus der Methode zu erstellen onCreateDialog() (siehe Anmerkung unten). Du zeigst sie durch showDialog(). Auf diese Weise behandelt Android die Rotation für Sie und Sie müssen nicht anrufen dismiss() im onPause() Um ein WindowLeak zu vermeiden, müssen Sie den Dialog nicht wiederherstellen. Aus den Dokumenten:

Zeigen Sie einen Dialog an, der von dieser Aktivität verwaltet wird. Ein Aufruf von onCreateDialog (int, Bundle) wird mit der gleichen ID durchgeführt, wenn dieser zum ersten Mal für eine bestimmte ID aufgerufen wird. Ab diesem Zeitpunkt wird der Dialog automatisch gespeichert und wiederhergestellt.

Sehen Android-Dokumente showDialog () Für mehr Information. Hoffe es hilft jemandem!

Hinweis:Wenn Sie AlertDialog.Builder verwenden, rufen Sie nicht auf show() von onCreateDialog(), Anruf create() stattdessen. Wenn Sie ProgressDialog verwenden, erstellen Sie einfach das Objekt, legen Sie die benötigten Parameter fest und geben Sie es zurück. Abschließend, show() Innerhalb onCreateDialog() Probleme verursachen, einfach die Dialog-Instanz erstellen und zurückgeben. Das sollte funktionieren! (Ich habe Probleme bei der Verwendung von showDialog () von onCreate () - das Dialogfeld wird nicht angezeigt, aber wenn Sie es in OnResume () oder in einem Listener-Callback verwenden, funktioniert es gut).


1
2018-02-05 22:29



Sie können das kombinieren Dialog ist onSave / onRestore Methoden mit dem Aktivität onSave / onRestore Methoden, um den Status des Dialogs beizubehalten.

Hinweis: Diese Methode funktioniert für diese "einfachen" Dialoge, z. B. um eine Warnmeldung anzuzeigen. Es wird nicht den Inhalt eines in einem Dialog eingebetteten WebView reproduzieren. Wenn Sie wirklich verhindern möchten, dass ein komplexes Dialogfeld während der Rotation verworfen wird, versuchen Sie es mit der Methode von Chung IW.

@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
     super.onRestoreInstanceState(savedInstanceState);
     myDialog.onRestoreInstanceState(savedInstanceState.getBundle("DIALOG"));
     // Put your codes to retrieve the EditText contents and 
     // assign them to the EditText here.
}

@Override
protected void onSaveInstanceState(Bundle outState) {
     super.onSaveInstanceState(outState);
     // Put your codes to save the EditText contents and put them 
     // to the outState Bundle here.
     outState.putBundle("DIALOG", myDialog.onSaveInstanceState());
}

1
2018-02-03 23:57