Verhindern Sie, dass die Schaltfläche "Zurück" ein Dialogfeld schließt

73

Ich versuche zu verhindern, dass ein AlertDialogfeld geschlossen wird, wenn die Zurück-Taste in Android gedrückt wird. Ich habe beide gängigen Methoden in diesem Thread befolgt , und mit System.out.println kann ich sehen, dass der Code in beiden Fällen ausgeführt wird. Die Schaltfläche Zurück schließt jedoch weiterhin das Dialogfeld.

Was könnte ich falsch machen? Letztendlich versuche ich zu verhindern, dass die Schaltfläche "Zurück" ein Dialogfeld schließt. Dies ist ein Haftungsausschluss, der beim ersten Ausführen der App angezeigt wird. Ich möchte nicht, dass der Benutzer eine andere Option hat, als die Schaltfläche "Akzeptieren" zu drücken Damit die App fortgesetzt werden kann.

CaptainProg
quelle
1
Wenn Sie einen Benutzer benötigen eine Lizenz oder ein Haftungsausschluss (oder was auch immer) zu akzeptieren , dann Sie muss es ihnen ermöglichen, zu verweigern. Wenn sie auf die BACKSchaltfläche klicken, stellen Sie sicher, dass Ihr Lizenz- / Haftungsausschlussdialog beim nächsten Start der App immer wieder angezeigt wird, bis sie die App entweder akzeptieren oder von ihrem Gerät entfernen. Wenn Sie sich für den von Sam vorgeschlagenen Ansatz entscheiden, MÜSSEN Sie eine Schaltfläche "Ablehnen" bereitstellen und die Lizenz / den Haftungsausschluss beim nächsten Start der App neu erstellen.
Squonk
1
Ich würde eine App entfernen, die mir als einzige Option "Akzeptieren" gibt ... und nicht einmal daran denken, die Home-Taste zu deaktivieren!
WarrenFaith
Die App kann durch Drücken der Home-Taste geschlossen werden, aber im Wesentlichen kann die App den Haftungsausschluss nicht überschreiten, wenn die Lizenz nicht akzeptiert wird. @Squonk, Sie erwähnen, dass ich ihnen erlauben muss , sich zu weigern; Ist das ein rechtliches Problem? dh gibt es ein Gesetz, dass Software verwendbar sein muss (wenn sie bezahlt wurde), ohne die Lizenzvereinbarung zu akzeptieren? nb Ich habe bereits eine Schaltfläche zum Ablehnen. Wenn Sie diese Schaltfläche drücken, wird ein Toast () angezeigt, der besagt, dass Sie die Vereinbarung akzeptieren müssen, um die App nutzen zu können. Das Dialogfeld bleibt somit bestehen, bis Akzeptieren gedrückt wird.
CaptainProg
1
@CaptainProg: Ich bin kein Anwalt, aber ich vermute in einigen Ländern, dass dies als rechtliches Problem angesehen werden könnte. Ich schlage nicht vor, dass Sie Leuten erlauben, Ihre App zu verwenden, wenn sie den Haftungsausschluss ablehnen / ablehnen. Ich sage nur, es ist eine schlechte Richtlinie, schlechte Kundenbeziehungen (auch wenn die App kostenlos ist) und schlecht für die UX, jemanden einzuschließen. Lassen Sie einfach die Option "Ablehnen" die App schließen und das nächste Mal, wenn der Benutzer versucht zu starten Präsentieren Sie den gleichen Dialog. Popup a nicht einfach Toast, lass sie eingesperrt und verlasse HOMEdich darauf , dass du mit der Taste thw rauskommst .
Squonk

Antworten:

170

Verwenden Sie einfach die setCancelable()Funktion:

AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setCancelable(false);

Dadurch wird verhindert, dass die Schaltfläche "Zurück" den Dialog schließt, die Schaltfläche "Negativ" bleibt jedoch erhalten, wenn Sie sie verwenden möchten.


Während jeder Benutzer, der Ihre Nutzungsbedingungen nicht akzeptieren möchte, die Home-Taste drücken kann, gibt es angesichts des Kommentars von Squonk zwei weitere Möglichkeiten, um zu verhindern, dass er von der Benutzervereinbarung zurücktritt. Eine ist eine einfache Schaltfläche "Ablehnen" und die andere überschreibt die Schaltfläche "Zurück" im Dialogfeld:

builder.setNegativeButton("Refuse", new OnClickListener() {
           @Override
           public void onClick(DialogInterface dialog, int which) {
               finish();
           }
       })
       .setOnKeyListener(new OnKeyListener() {
           @Override
           public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
               if(keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_UP)
                   finish();
               return false;
           }
       });
Sam
quelle
37
Wenn Sie ein verwenden DialogFragment, sollten Sie setCancelabledas und nicht das Dialogselbst aufrufen
Kuffs
Vielen Dank @Kuffs. Ich habe es im Dialog eingestellt und mich gefragt, warum es nicht funktioniert!
Sasikt
21

Um zu verhindern, dass die Zurück-Schaltfläche einen Dialog schließt (ohne von der Aktivität abhängig zu sein), geben Sie einfach den folgenden Code ein:

alertDialog.setOnKeyListener(new DialogInterface.OnKeyListener() {
    @Override
    public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
        // Prevent dialog close on back press button
        return keyCode == KeyEvent.KEYCODE_BACK;
    }
});
falvojr
quelle
1
Hat in meinem Fall wunderbar funktioniert. Ich musste ein WebViewauf meine App laden . Ich musste canGoBack()den Dialog überprüfen und schließen, wenn er falsch war.
PNDA
16

Bei der Verwendung müssen DialogFragmentSie setCancelable()das Fragment aufrufen , nicht den Dialog:

@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
    dialog = new ProgressDialog(getActivity());
    dialog.setIndeterminate(true);
    dialog.setMessage(...);
    setCancelable(false);

    return dialog;
}

Anrufe dialog.setCancelable()scheinen keine Wirkung zu haben. Es scheint, dass DialogFragmentdie Einstellung des Dialogfelds für die Abbruchfähigkeit nicht beachtet wird.

Ognyan
quelle
3

Verwenden setCancelable(false)

SampleDialog sampleDialog = SampleDialog.newInstance();
sampleDialog.setCancelable(false);
sampleDialog.show(getSupportFragmentManager(), SampleDialog.class.getSimpleName());
David
quelle
0

Nur das hat bei mir funktioniert:

AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle(title);
builder.setMessage(content);

/**
 * Make it when the Back button is pressed, the dialog isn't dismissed.
 */
builder.setOnKeyListener(new DialogInterface.OnKeyListener() {
    @Override
    public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
        if(keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_UP) {
            Utilities.makeToast(getContext(), "There is no way back!");
            return true; // Consumed
        }
        else {
            return false; // Not consumed
        }
    }
});

Dialog dialog = builder.create();

/**
 * Make it so touching on the background activity doesn't close the dialog
 */
dialog.setCanceledOnTouchOutside(false);

return dialog;

Wie Sie sehen, habe ich auch eine dialog.setCanceledOnTouchOutside(false);Zeile hinzugefügt , damit das Tippen außerhalb des Dialogfelds auch nicht dazu führt, dass es geschlossen wird.

Ban-Geoengineering
quelle
0

In JQuery Mobile fügt ein Popup der URL einen Hash hinzu. Mit dem folgenden Code kann die Rückseite das Popup beim Öffnen schließen und beim Schließen zur App zurückkehren. Sie können dieselbe Logik für ein benutzerdefiniertes UI-Framework verwenden.

@Override
public void onBackPressed() {

    // check if modal is open #&ui-state=dialog

    if (webView.getVisibility() == View.VISIBLE && webView.getUrl().contains("#&ui-state=dialog")) {
        // don't pass back button action
        if (webView.canGoBack()) {
            webView.goBack();
        }
    } else {
        // pass back button action
        super.onBackPressed();
    }
}
Ricardo Saracino
quelle
0
AlertDialog.Builder builder = AlertDialog.Builder(this)
Dialog dialog = builder.create()
dialog.setCancelable(false)
dialog.setCanceledOnTouchOutside(false)

Dadurch wird verhindert, dass der Benutzer den Dialog abbricht, wenn er die Zurück-Taste drückt oder außerhalb des Dialogfensters berührt

Iancu Vlad
quelle