Ich habe einen benutzerdefinierten Dialog für meine Anwendung implementiert. Ich möchte das implementieren, wenn der Benutzer außerhalb des Dialogs klickt, wird der Dialog verworfen. Was muss ich dafür tun?
Sie können dialog.setCanceledOnTouchOutside(true);
verwenden, um den Dialog zu schließen, wenn Sie außerhalb des Dialogs berühren.
So etwas wie,
Dialog dialog = new Dialog(context)
dialog.setCanceledOnTouchOutside(true);
Oder wenn Ihr Dialog dann nicht im Modell ist,
1 - Setzen Sie das Flag -FLAG_NOT_TOUCH_MODAL
für das Fensterattribut Ihres Dialogs
Window window = this.getWindow();
window.setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL,
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);
2 - Fügen Sie den Fenstereigenschaften ein weiteres Flag hinzu, FLAG_WATCH_OUTSIDE_TOUCH
- Dieses Dialogfeld dient dazu, ein Berührungsereignis außerhalb des sichtbaren Bereichs zu empfangen.
3 - Überschreiben Sie onTouchEvent()
des Dialogs und überprüfen Sie den Aktionstyp. Wenn der Aktionstyp 'MotionEvent.ACTION_OUTSIDE
'bedeutet, interagiert der Benutzer außerhalb des Dialogbereichs. In diesem Fall können Sie also Ihren Dialog verkleinern oder entscheiden, was Sie ausführen möchten.
public boolean onTouchEvent(MotionEvent event)
{
if(event.getAction() == MotionEvent.ACTION_OUTSIDE){
System.out.println("TOuch outside the dialog ******************** ");
this.dismiss();
}
return false;
}
Weitere Informationen finden Sie unter Wie kann ich ein benutzerdefiniertes Dialogfeld basierend auf Berührungspunkten abweisen? und So schließen Sie Ihren nichtmodalen Dialog, wenn Sie außerhalb des Dialogbereichs berühren
Sie können diese Implementierung von onTouchEvent verwenden. Es verhindert, dass auf das Berührungsereignis (wie howettl) unter Aktivität reagiert wird.
@Override
public boolean onTouchEvent ( MotionEvent event ) {
// I only care if the event is an UP action
if ( event.getAction () == MotionEvent.ACTION_UP ) {
// create a rect for storing the window rect
Rect r = new Rect ( 0, 0, 0, 0 );
// retrieve the windows rect
this.getWindow ().getDecorView ().getHitRect ( r );
// check if the event position is inside the window rect
boolean intersects = r.contains ( (int) event.getX (), (int) event.getY () );
// if the event is not inside then we can close the activity
if ( !intersects ) {
// close the activity
this.finish ();
// notify that we consumed this event
return true;
}
}
// let the system handle the event
return super.onTouchEvent ( event );
}
Quelle: http://blog.twimager.com/2010/08/closing-activity-by-touching-outside.html
Einfach verwenden
dialog.setCanceledOnTouchOutside(true);
Wenn Sie das Dialogfeld mit einem in Ihrer XML-Formatvorlage definierten Design anpassen, fügen Sie diese Zeile in Ihr Design ein:
<item name="Android:windowCloseOnTouchOutside">true</item>
dialog.setCanceledOnTouchOutside(true);
um den Dialog bei Berührung außerhalb zu schließen.
Und wenn Sie die Berührung von außen nicht schließen möchten, verwenden Sie den folgenden Code:
dialog.setCanceledOnTouchOutside(false);
Bei dieser Methode sollten Aktivitäten unterhalb des grauen Bereichs vollständig vermieden werden, indem Klickereignisse abgerufen werden.
Entfernen Sie diese Zeile, wenn Sie es haben:
window.setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL, WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);
Setzen Sie dies auf Ihre erstellte Aktivität
getWindow().setFlags(LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH, LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH);
dann überschreiben Sie das Berührungsereignis mit diesem
@Override
public boolean onTouchEvent(MotionEvent ev)
{
if(MotionEvent.ACTION_DOWN == ev.getAction())
{
Rect dialogBounds = new Rect();
getWindow().getDecorView().getHitRect(dialogBounds);
if (!dialogBounds.contains((int) ev.getX(), (int) ev.getY())) {
// You have clicked the grey area
displayYourDialog();
return false; // stop activity closing
}
}
// Touch events inside are fine.
return super.onTouchEvent(ev);
}
Sie können dies versuchen: -
AlterDialog alterdialog;
alertDialog.setCanceledOnTouchOutside(true);
oder
alertDialog.setCancelable(true);
Und wenn Sie einen AlterDialog.Builder
haben, können Sie folgendes versuchen: -
alertDialogBuilder.setCancelable(true);
Dieser Code wird verwendet, wenn beim Klicken auf das Dialogfeld die Zeit eingeblendet wird und wenn der Benutzer auf die äußere Seite des Dialogfelds klickt, wenn sowohl der Soft-Input als auch das Dialogfeld geschlossen sind.
dialog = new Dialog(act) {
@Override
public boolean onTouchEvent(MotionEvent event) {
// Tap anywhere to close dialog.
Rect dialogBounds = new Rect();
getWindow().getDecorView().getHitRect(dialogBounds);
if (!dialogBounds.contains((int) event.getX(),
(int) event.getY())) {
// You have clicked the grey area
InputMethodManager inputMethodManager = (InputMethodManager) act
.getSystemService(act.INPUT_METHOD_SERVICE);
inputMethodManager.hideSoftInputFromWindow(dialog
.getCurrentFocus().getWindowToken(), 0);
dialog.dismiss();
// stop activity closing
} else {
InputMethodManager inputMethodManager = (InputMethodManager) act
.getSystemService(act.INPUT_METHOD_SERVICE);
inputMethodManager.hideSoftInputFromWindow(dialog
.getCurrentFocus().getWindowToken(), 0);
}
return true;
}
};
Bei einer anderen Lösung wurde dieser Code aus dem Android-Quellcode von Window
.__ abgeschnitten. Sie sollten diese beiden Methoden einfach zum Dialog-Quellcode hinzufügen.
@Override
public boolean onTouchEvent(MotionEvent event) {
if (isShowing() && (event.getAction() == MotionEvent.ACTION_DOWN
&& isOutOfBounds(getContext(), event) && getWindow().peekDecorView() != null)) {
hide();
}
return false;
}
private boolean isOutOfBounds(Context context, MotionEvent event) {
final int x = (int) event.getX();
final int y = (int) event.getY();
final int slop = ViewConfiguration.get(context).getScaledWindowTouchSlop();
final View decorView = getWindow().getDecorView();
return (x < -slop) || (y < -slop)
|| (x > (decorView.getWidth()+slop))
|| (y > (decorView.getHeight()+slop));
}
Diese Lösung hat dieses Problem nicht:
Dies funktioniert hervorragend, mit der Ausnahme, dass die Aktivität darunter auch auf das Berührungsereignis reagiert. Gibt es eine Möglichkeit, dies zu verhindern? - Howettl
Rufen Sie dialog.setCancelable(false);
aus Ihrer Aktivität/Ihrem Fragment auf.
Sie können eine background
machen, die die gesamte Bildschirmgröße transparent
einnimmt, und das onClick
-Ereignis auf dismiss
hören.