Je me demandais s'il était possible de cliquer d'une manière ou d'une autre en dehors d'une boîte de dialogue contextuelle (ou d'une activité avec un thème de boîte de dialogue) et de la rejeter en appuyant simplement en dehors de celle-ci?
J'ai fait une photo rapide pour l'illustrer:
Normalement, vous devez appuyer sur la touche Retour pour fermer les boîtes de dialogue, mais sous Honeycomb, il pourrait être intéressant de pouvoir taper en dehors de la boîte de dialogue, en raison de la totalité de l'écran.
Mon application est une activité unique avec Theme.Holo.Dialog. Dans mon cas, l'autre réponse n'a pas fonctionné. Seules les autres applications d'arrière-plan ou l'écran de lancement étaient conçues pour recevoir des événements tactiles.
J'ai trouvé que l'utilisation de dispatchTouchEvent fonctionne dans mon cas. Je pense que c'est aussi une solution plus simple. Voici un exemple de code sur la façon de l'utiliser pour détecter des taps en dehors de l'activité avec un thème de dialogue:
@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)
Définit si cette boîte de dialogue est annulée lorsque touché en dehors des limites de la fenêtre.
Il existe une méthode TouchInterceptor
qui sera appelée lorsque vous toucherez du côté extérieur de la fenêtre contextuelle.
Par exemple
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
est la fenêtre popup
Et si vous voulez la même fonctionnalité pour l'activité, vous devez suivre les étapes ci-dessous.
1) Ajouter un indicateur avant la méthode setContentView()
appelée dans onCreate();
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) Remplacer l'événement onTouchEvent()
dans l'activité
et écrivez ci-dessous le code
@Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_OUTSIDE) {
Toast.makeText(getApplicationContext(), "Finish", 3000).show();
finish();
return true;
}
return false;
}
La copie complète est ici
Activité
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;
}
}
Ceci est 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>
Vous pouvez utiliser Activity # setFinishOnTouchOutside aussi, si votre boîte de dialogue est une Activity
. Ce doit être le moyen le plus court pour Activity
s;)
(C'est l'API 11+ cependant. Mais l'API <= 10 est généralement de taille d'écran normale.)
Vous pouvez utiliser
dialog.setCancelable(true\false);
Pour les dernières versions d'Android;
Cela désactivera l'événement OutSide Touch.
J'écris simplement dialog.setCanceledOnTouchOutside (false); et ça marche pour moi, la fenêtre ne sera pas fermée au robinet extérieur.
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);
Vérifiez si vous avez cette ligne de code ou non ....
dialog.setCanceledOnTouchOutside(true);
Utilisez un style de dialogue plutôt que d'autres styles.
Par exemple, utiliser
public YourCustomDialog(Context context) {
super(context, Android.R.style.Theme_Holo_dialog_NoActionBar);
}
Lorsque vous utilisez d'autres styles tels que Theme_Translucent_NoTitleBar , la boîte de dialogue ne sera pas fermée.
this.setFinishOnTouchOutside (false);
tu peux utiliser ça
Ancienne question mais encore une autre solution:
Faites votre activité de premier plan en plein écran. Mises en page utilisées: La mise en page plein écran doit avoir un fond transparent (par exemple, @null
ou @Android:color/transparent
). La disposition interne doit avoir un arrière-plan visible.
Ajoutez une OnClickListener
à la présentation externe invisible qui finish()
es votre activité.
Toutes les vues de la boîte de dialogue peuvent être configurées pour utiliser l'événement tactile afin que l'appel ci-dessous ne soit pas appelé.
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;
J'ai ajouté ceci et cela fonctionne parfaitement sur la version 3.0, mais devrait fonctionner sur tous.