Ich habe einen benutzerdefinierten Dialog für meine Anwendung implementiert. Ich möchte implementieren, dass der Dialog geschlossen wird, wenn der Benutzer außerhalb des Dialogfelds klickt. Was muss ich dafür tun?
Ich habe einen benutzerdefinierten Dialog für meine Anwendung implementiert. Ich möchte implementieren, dass der Dialog geschlossen wird, wenn der Benutzer außerhalb des Dialogfelds klickt. Was muss ich dafür tun?
Antworten:
Sie können verwenden dialog.setCanceledOnTouchOutside(true);
, um den Dialog zu schließen, wenn Sie außerhalb des Dialogs berühren.
Etwas wie,
Dialog dialog = new Dialog(context)
dialog.setCanceledOnTouchOutside(true);
Oder wenn Ihr Dialog dann nicht modelliert ist,
1 - Setzen Sie das Flag FLAG_NOT_TOUCH_MODAL
für das Fensterattribut Ihres Dialogfelds
Window window = this.getWindow();
window.setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL,
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);
2 - Fügen Sie den Windows-Eigenschaften ein weiteres Flag hinzu. FLAG_WATCH_OUTSIDE_TOUCH
- Dieses Flag dient zum Empfangen von Berührungsereignissen außerhalb des sichtbaren Bereichs.
3 - onTouchEvent()
Dialog überschreiben und nach Aktionstyp suchen. Wenn der Aktionstyp ' MotionEvent.ACTION_OUTSIDE
' bedeutet, interagiert der Benutzer außerhalb des Dialogbereichs. In diesem Fall können Sie Ihren Dialog verkleinern oder entscheiden, was Sie ausführen möchten. Klartext anzeigen?
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 So schließen Sie ein benutzerdefiniertes Dialogfeld basierend auf Berührungspunkten. und So schließen Sie Ihren nicht modalen Dialog, wenn Sie ihn außerhalb des Dialogbereichs berühren
Einfach benutzen
dialog.setCanceledOnTouchOutside(true);
Sie können diese Implementierung von onTouchEvent verwenden. Es verhindert, dass unter Aktivität auf das Berührungsereignis reagiert wird (wie bereits erwähnt).
@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
Wenn Sie den Dialog mit einem in Ihrer XML-Stil definierten Thema anpassen, fügen Sie diese Zeile in Ihr Thema ein:
<item name="android:windowCloseOnTouchOutside">true</item>
dialog.setCanceledOnTouchOutside(true);
funktioniert wunderbar.
Diese Methode sollte Aktivitäten unterhalb des grauen Bereichs, bei denen Klickereignisse abgerufen werden, vollständig vermeiden.
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);
Überschreiben Sie dann das Berührungsereignis damit
@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);
}
Dieser Code wird verwendet, wenn Sie beim Klicken auf das Dialogfeld klicken, um die Eingabe zu verbergen, und wenn der Benutzer zu diesem Zeitpunkt auf die Außenseite des Dialogfelds klickt, wenn sowohl die Soft-Eingabe 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;
}
};
Eine andere Lösung, dieser Code wurde aus dem Android-Quellcode von Window
Sie sollten nur diese beiden Methoden zu Ihrem 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, außer dass die Aktivität darunter auch auf das Berührungsereignis reagiert. Gibt es eine Möglichkeit, dies zu verhindern? - Howettl
Folgendes hat bei mir funktioniert:
myDialog.setCanceledOnTouchOutside(true);
Hier ist der Code
dialog.getWindow().getDecorView().setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent ev) {
if(MotionEvent.ACTION_DOWN == ev.getAction())
{
Rect dialogBounds = new Rect();
dialog. getWindow().getDecorView().getHitRect(dialogBounds);
if (!dialogBounds.contains((int) ev.getX(), (int) ev.getY())) {
// You have clicked the grey area
UiUtils.hideKeyboard2(getActivity());
return false; // stop activity closing
}
}
getActivity().dispatchTouchEvent(ev);
return false;
}
});
Probier diese . Sie können die Tastatur ausblenden, wenn Sie draußen berühren