Comment rejeter la boîte de dialogue en cliquant sur en dehors de la boîte de dialogue?
j'ai implémenté un dialogue personnalisé pour mon application. Je tiens à mettre en œuvre que lorsque l'utilisateur clique en dehors de la boîte de dialogue, celle-ci sera rejetée. Que dois-je faire pour cela?
11 réponses
vous pouvez utiliser dialog.setCanceledOnTouchOutside(true);
qui fermera le dialogue si vous touchez en dehors du dialogue.
quelque chose comme,
Dialog dialog = new Dialog(context)
dialog.setCanceledOnTouchOutside(true);
Ou si votre boîte de Dialogue non-modèle, puis,
1 - Mettez le drapeau - FLAG_NOT_TOUCH_MODAL
pour l'attribut de fenêtre de votre dialogue
Window window = this.getWindow();
window.setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL,
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);
2-Ajouter un autre drapeau aux propriétés de windows, FLAG_WATCH_OUTSIDE_TOUCH
- celui-ci est pour que dialog reçoive l'événement touch en dehors de sa région visible.
3 - Remplacer onTouchEvent()
de dialogue et de vérifier par type d'action. si le type d'action est
' MotionEvent.ACTION_OUTSIDE
' signifie que l'utilisateur interagit en dehors de la zone de dialogue. Ainsi, dans ce cas, vous pouvez diminuer votre dialogue ou décider ce que vous vouliez effectuer.
vue plainprint?
public boolean onTouchEvent(MotionEvent event)
{
if(event.getAction() == MotionEvent.ACTION_OUTSIDE){
System.out.println("TOuch outside the dialog ******************** ");
this.dismiss();
}
return false;
}
pour plus d'informations regardez comment rejeter un dialogue personnalisé basé sur des points de contact? et comment rejeter votre dialogue non-modal, quand touché à l'extérieur de la zone de dialogue
vous pouvez utiliser cette implémentation de onTouchEvent. Il empêche de réagir en dessous de l'activité à l'événement de toucher (comme mentionné howettl).
@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 );
}
Source: http://blog.twimager.com/2010/08/closing-activity-by-touching-outside.html
utilisation simple
dialog.setCanceledOnTouchOutside(true);
ou, si vous personnalisez la boîte de dialogue en utilisant un thème défini dans votre style xml, mettez cette ligne dans votre thème:
<item name="android:windowCloseOnTouchOutside">true</item>
dialog.setCanceledOnTouchOutside(true);
pour fermer le dialogue sur le toucher extérieur.
et si vous ne voulez pas fermer à l'extérieur, utilisez le code ci-dessous:
dialog.setCanceledOnTouchOutside(false);
cette méthode devrait éviter complètement les activités sous les événements de clic de récupération de zone grise.
Supprimer cette ligne si vous l'avez:
window.setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL, WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);
mettez ceci sur votre activité créée
getWindow().setFlags(LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH, LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH);
puis annuler l'événement tactile avec ce
@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);
}
vous pouvez essayer ceci: -
AlterDialog alterdialog;
alertDialog.setCanceledOnTouchOutside(true);
ou
alertDialog.setCancelable(true);
Et si vous avez un AlterDialog.Builder
, Alors vous pouvez essayer ceci:-
alertDialogBuilder.setCancelable(true);
une autre solution ce code a été découpé à partir du code source android de Window
Vous devez juste ajouter ces deux méthodes à votre code source de dialogue.
@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));
}
Cette solution n'a pas ce problème:
Cela fonctionne très bien, sauf que l'activité sous réagit également à l'événement tactile. Est-il un moyen pour éviter cela? - howettl 151930920"
ce code est utilisé pour quand l'utilisation cliquer sur boîte de dialogue que le temps hidesoftinput et quand l'utilisateur cliquer côté extérieur de boîte de dialogue que le temps softinput et boîte de dialogue sont proches.
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;
}
};
vous pouvez faire un background
occupant toute la taille de l'écran transparent
et écouter l'événement onClick
à dismiss
il.
Appel dialog.setCancelable(false);
à partir de votre activité/fragment.