Ich habe mich gefragt, ob es möglich ist, außerhalb eines Popup-Dialogfelds (oder einer Aktivität mit einem Dialogdesign) zu tippen, und es durch einfaches Tippen außerhalb abzubrechen.
Ich machte ein kurzes Bild, um es zu veranschaulichen:
Normalerweise müssen Sie die Zurück-Taste drücken, um die Dialogfelder zu schließen. Bei Honeycomb kann es jedoch großartig sein, die Option zu haben, nur außerhalb des Dialogs zu tippen, da alle Bildschirminhalte vorhanden sind.
Meine App ist eine einzige Aktivität mit Theme.Holo.Dialog. In meinem Fall hat die andere Antwort nicht funktioniert. Es wurden nur die anderen Hintergrund-Apps oder der Startbildschirm für den Empfang von Touch-Events erstellt.
Ich habe festgestellt, dass die Verwendung von dispatchTouchEvent in meinem Fall funktioniert. Ich denke, es ist auch eine einfachere Lösung. Im Folgenden finden Sie einige Beispiele für die Verwendung von Taps außerhalb der Aktivität mit einem Dialogdesign:
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
Rect dialogBounds = new Rect();
getWindow().getDecorView().getHitRect(dialogBounds);
if (!dialogBounds.contains((int) ev.getX(), (int) ev.getY())) {
// Tapped outside so we finish the activity
this.finish();
}
return super.dispatchTouchEvent(ev);
}
dialog.setCanceledOnTouchOutside(true)
Legt fest, ob dieser Dialog abgebrochen wird, wenn er außerhalb der Fenstergrenzen berührt wird.
Es gibt eine TouchInterceptor
-Methode, die aufgerufen wird, wenn Sie außerhalb des Popup-Fensters berühren
Zum Beispiel
mWindow.setTouchInterceptor(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_OUTSIDE) {
mWindow.dismiss();
return true;
}
return false;
}
});
mWindow
ist das Popup-Fenster
Und wenn Sie dieselbe Funktionalität für Activity wünschen, müssen Sie die folgenden Schritte befolgen.
1) Flag vor der setContentView()
-Methode hinzufügen, die in onCreate();
aufgerufen wird
getWindow().setFlags(LayoutParams.FLAG_NOT_TOUCH_MODAL, LayoutParams.FLAG_NOT_TOUCH_MODAL);
// ...but notify us that it happened.
getWindow().setFlags(LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH, LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH);
2) Überschreiben Sie onTouchEvent()
in Activity
und schreibe den Code
@Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_OUTSIDE) {
Toast.makeText(getApplicationContext(), "Finish", 3000).show();
finish();
return true;
}
return false;
}
Die vollständige Kopie ist hier
Aktivität
package net.londatiga.Android;
import Android.app.Activity;
import Android.os.Bundle;
import Android.view.MotionEvent;
import Android.view.View;
import Android.view.View.OnClickListener;
import Android.view.View.OnTouchListener;
import Android.view.WindowManager.LayoutParams;
import Android.widget.Button;
import Android.widget.Toast;
public class NewQuickAction3DActivity extends Activity implements OnTouchListener {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Make us non-modal, so that others can receive touch events.
getWindow().setFlags(LayoutParams.FLAG_NOT_TOUCH_MODAL, LayoutParams.FLAG_NOT_TOUCH_MODAL);
// ...but notify us that it happened.
getWindow().setFlags(LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH, LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH);
setContentView(R.layout.main);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_OUTSIDE) {
Toast.makeText(getApplicationContext(), "Hi", 3000).show();
return true;
}
return false;
}
}
Dies ist manifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:Android="http://schemas.Android.com/apk/res/Android"
package="net.londatiga.Android"
Android:versionCode="1"
Android:versionName="1.0">
<uses-sdk Android:minSdkVersion="7" />
<application Android:icon="@drawable/icon" Android:label="@string/app_name">
<activity Android:name=".NewQuickAction3DActivity"
Android:label="@string/app_name" Android:theme="@Android:style/Theme.Holo.Dialog">
<intent-filter>
<action Android:name="Android.intent.action.MAIN" />
<category Android:name="Android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Sie könnten auch Activity # setFinishOnTouchOutside verwenden, wenn Ihr Dialog eine Activity
ist. Das muss der kürzeste Weg für Activity
s sein;)
(Es ist jedoch API 11+. Aber API <= 10 hat im Allgemeinen eine normale Bildschirmgröße.)
Sie können verwenden
dialog.setCancelable(true\false);
Für die neuesten Versionen von Android;
Dadurch wird das outSide Touch-Ereignis deaktiviert.
Ich schreibe einfach dialog.setCanceledOnTouchOutside (false); und es funktioniert für mich, Fenster wird nicht von außen abgetippt.
dialog = new Dialog(MainActivity.this);
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.setContentView(R.layout.dialog_layout);
dialog.getWindow().setBackgroundDrawableResource(
Android.R.color.transparent);
dialog.setCancelable(false);
dialog.setCanceledOnTouchOutside(true);
Prüfen Sie, ob Sie diese Codezeile haben oder nicht ....
dialog.setCanceledOnTouchOutside(true);
Verwenden Sie eher den Stil des Dialogs als andere Stile.
Zum Beispiel verwenden
public YourCustomDialog(Context context) {
super(context, Android.R.style.Theme_Holo_dialog_NoActionBar);
}
Wenn Sie andere Stile wie Theme_Translucent_NoTitleBar verwenden, wird der Dialog nicht abgebrochen.
this.setFinishOnTouchOutside (false);
sie können dies verwenden
Alte Frage, aber noch eine andere Lösung:
Machen Sie Ihre Vordergrundaktivität im Vollbildmodus. Usenested Layouts: Das Vollbild-Layout sollte einen transparenten Hintergrund haben (z. B. @null
oder @Android:color/transparent
). Das innere Layout sollte einen sichtbaren Hintergrund haben.
Fügen Sie dem unsichtbaren äußeren Layout eine OnClickListener
hinzu, die Ihre Aktivität finish()
es macht.
Alle Ansichten innerhalb des Dialogs können so eingestellt werden, dass das Berührungsereignis verbraucht wird, sodass unten nicht aufgerufen wird.
onCreate(){
getWindow().getDecorView().getRootView().setOnTouchListener(new OnTouchListener(){
@Override
public boolean onTouch(View v, MotionEvent event) {
dialog.dismiss();
return false;
}
});
LayoutParams lp=dialogp.getWindow().getAttributes();
lp.flags=LayoutParams.FLAG_LAYOUT_NO_LIMITS;
Ich habe dies hinzugefügt und es funktioniert einwandfrei ab 3.0, sollte aber bei allen funktionieren.