J'ai implémenté une boîte de dialogue personnalisée pour mon application. Je veux implémenter que lorsque l'utilisateur clique en dehors de la boîte de dialogue, la boîte de dialogue sera fermée. Que dois-je faire pour cela?
J'ai implémenté une boîte de dialogue personnalisée pour mon application. Je veux implémenter que lorsque l'utilisateur clique en dehors de la boîte de dialogue, la boîte de dialogue sera fermée. Que dois-je faire pour cela?
Réponses:
Vous pouvez utiliser dialog.setCanceledOnTouchOutside(true);
ce qui fermera la boîte de dialogue si vous touchez en dehors de la boîte de dialogue.
Quelque chose comme,
Dialog dialog = new Dialog(context)
dialog.setCanceledOnTouchOutside(true);
Ou si votre boîte de dialogue n'est pas un modèle alors,
1 - Définissez le drapeau- FLAG_NOT_TOUCH_MODAL
pour l'attribut de fenêtre de votre boîte de dialogue
Window window = this.getWindow();
window.setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL,
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);
2 - Ajoutez un autre drapeau aux propriétés de Windows ,, FLAG_WATCH_OUTSIDE_TOUCH
- celui-ci est pour que le dialogue reçoive un événement tactile en dehors de sa région visible.
3 - Remplacer la onTouchEvent()
boîte de dialogue et vérifier le type d'action. si le type d'action est « MotionEvent.ACTION_OUTSIDE
» signifie que l'utilisateur interagit en dehors de la zone de dialogue. Donc, dans ce cas, vous pouvez fermer votre boîte de dialogue ou décider de ce que vous souhaitez effectuer. voir le papier ordinaire?
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, consultez Comment fermer une boîte de dialogue personnalisée basée sur les points de contact? et Comment fermer votre boîte de dialogue non modale, lorsqu'elle est touchée en dehors de la zone de dialogue
Utilisez simplement
dialog.setCanceledOnTouchOutside(true);
Vous pouvez utiliser cette implémentation de onTouchEvent. Il empêche de réagir sous l'activité à l'événement tactile (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
Ou, si vous personnalisez la boîte de dialogue à l'aide d'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);
fonctionne à merveille.
Cette méthode doit complètement éviter les activités sous la zone grise de récupération des événements de clic.
Supprimez 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 écraser 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);
}
Ce code est utilisé lors de l'utilisation, cliquez sur la boîte de dialogue pour masquer l'entrée logicielle et lorsque l'utilisateur clique sur le côté extérieur de la boîte de dialogue, lorsque l'entrée logicielle et la boîte de dialogue sont fermées.
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;
}
};
Une autre solution, ce code a été tiré du code source Android de Window
Vous devez simplement ajouter ces deux méthodes au code source de votre boîte 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é en dessous réagit également à l'événement tactile. Y a-t-il un moyen d'éviter cela? - hurlement
La suite a fonctionné pour moi:
myDialog.setCanceledOnTouchOutside(true);
Voici le 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;
}
});
Essaye celui-là . vous pouvez masquer le clavier lorsque vous touchez l'extérieur