J'ai une PopupWindow sur mon activité, le fait est que ma PopupWindow s'affiche même lorsque j'interagis avec mon activité (par exemple, le défilement de ma liste). Je peux faire défiler ma liste et la fenêtre Popup est toujours là.
Ce que je veux réaliser, c’est que lorsque je touche/défile/clique sur/etc sur l’écran qui n’est pas la Fenêtre Popup, je veux fermer la Fenêtre Popup. Juste comme fonctionne un menu. Si vous avez cliqué en dehors du menu, le menu sera fermé.
J'ai essayé setOutsideTouchable(true)
mais la fenêtre ne sera pas ignorée. Merci.
Essayez de définir setBackgroundDrawable
sur PopupWindow
qui devrait fermer la fenêtre si vous touchez en dehors de celle-ci.
J'ai trouvé qu'aucune des réponses fournies ne fonctionnait pour moi, à l'exception du commentaire de WareNinja sur la réponse acceptée, et celle de Marcin S. fonctionnera probablement également. Voici la partie qui fonctionne pour moi:
myPopupWindow.setBackgroundDrawable(new BitmapDrawable());
myPopupWindow.setOutsideTouchable(true);
Alternativement:
myPopupWindow.setFocusable(true);
Vous ne savez pas exactement quelles sont les différences, mais le code source de ListPopupWindow utilise en réalité ce dernier lorsque sa modalité est définie sur true avec setModal, de sorte qu'au moins les développeurs Android considèrent cette approche comme viable et qu'il ne s'agit que d'une ligne.
J'ai rencontré les mêmes problèmes, et corrigé comme ci-dessous les codes. Ça fonctionne bien pour moi.
// Closes the popup window when touch outside.
mPopupWindow.setOutsideTouchable(true);
mPopupWindow.setFocusable(true);
// Removes default background.
mPopupWindow.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
BTW, ne pas utiliser le constructeur obsolète BitmapDrawable, utilisez cenew ColorDrawable (Android.R.color.transparent)pour remplacer l'arrière-plan par défaut.
S'amuser@.@
Je sais qu'il est tard, mais je remarque que les gens ont toujours un problème avec la fenêtre contextuelle. J'ai décidé d'écrire un exemple totalement fonctionnel dans lequel vous pouvez fermer la fenêtre contextuelle en touchant ou en cliquant à l'extérieur de celle-ci ou en touchant simplement la fenêtre elle-même. Pour ce faire, créez une nouvelle classe PopupWindow et copiez ce code:
PopupWindow.class
public class PopupWindow extends Android.widget.PopupWindow
{
Context ctx;
Button btnDismiss;
TextView lblText;
View popupView;
public PopupWindow(Context context)
{
super(context);
ctx = context;
popupView = LayoutInflater.from(context).inflate(R.layout.popup, null);
setContentView(popupView);
btnDismiss = (Button)popupView.findViewById(R.id.btn_dismiss);
lblText = (TextView)popupView.findViewById(R.id.text);
setHeight(WindowManager.LayoutParams.WRAP_CONTENT);
setWidth(WindowManager.LayoutParams.WRAP_CONTENT);
// Closes the popup window when touch outside of it - when looses focus
setOutsideTouchable(true);
setFocusable(true);
// Removes default black background
setBackgroundDrawable(new BitmapDrawable());
btnDismiss.setOnClickListener(new Button.OnClickListener(){
@Override
public void onClick(View v) {
dismiss();
}});
// Closes the popup window when touch it
/* this.setTouchInterceptor(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_MOVE) {
dismiss();
}
return true;
}
}); */
} // End constructor
// Attaches the view to its parent anchor-view at position x and y
public void show(View anchor, int x, int y)
{
showAtLocation(anchor, Gravity.CENTER, x, y);
}
}
Créez maintenant la mise en page pour la fenêtre contextuelle: popup.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:layout_margin="1dp"
Android:orientation="vertical"
Android:padding="10dp" >
<TextView
Android:id="@+id/text"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:gravity="center"
Android:padding="5dp"
Android:text="PopupWindow Example"
Android:textColor="#000000"
Android:textSize="17sp"
Android:textStyle="italic" />
<FrameLayout
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:layout_gravity="center_vertical">
<Button
Android:id="@+id/btn_dismiss"
style="?android:attr/buttonStyleSmall"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:text="Dismiss"
Android:visibility="gone" />
<TextView
Android:id="@+id/lbl_dismiss"
Android:layout_width="fill_parent"
Android:layout_height="wrap_content"
Android:gravity="center"
Android:text="Touch outside of this box to dismiss"
Android:textColor="#ffffff"
Android:textStyle="bold" />
</FrameLayout>
Dans votre activité principale, créez une instance de la classe PopupWindow:
final PopupWindow popupWindow = new PopupWindow(this);
popupWindow.show(findViewById(R.id.YOUR_MAIN_LAYOUT), 0, -250);
où YOUR_MAIN_LAYOUT est la présentation de l'activité en cours dans laquelle popupWindow apparaîtra
Merci pour la réponse de @LunaKong et la confirmation de @ HourGlass. Je ne veux pas faire un commentaire en double, mais simplement le rendre clair et concis.
// Closes the popup window when touch outside. This method was written informatively in Google's docs.
mPopupWindow.setOutsideTouchable(true);
// Set focus true to prevent a touch event to go to a below view (main layout), which works like a dialog with 'cancel' property => Try it! And you will know what I mean.
mPopupWindow.setFocusable(true);
// Removes default background.
mPopupWindow.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
Mttdat.
Notez que pour annuler avec popupWindow.setOutsideTouchable(true)
, vous devez créer la largeur et la hauteur wrap_content
comme ci-dessous:
PopupWindow popupWindow = new PopupWindow(
G.layoutInflater.inflate(R.layout.lay_dialog_support, null, false),
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT, true);
popupWindow.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
popupWindow.setOutsideTouchable(true);
popupWindow.setFocusable(true);
popupWindow.showAtLocation(view, Gravity.RIGHT, 0, 0);
Pour une ListPopupWindow
, définissez la fenêtre sur modale à l’affichage.
mListPopupWindow.setModal(true);
De cette façon, un clic en dehors de la ListPopupWindow
le rejettera.
Définissez le fond de la fenêtre transparent:
PopupWindow.getBackground().setAlpha(0);
Après cela, définissez votre arrière-plan dans la mise en page. Fonctionne bien.
mPopWindow.setFocusable(true);
Le travail de suggestion de @LunaKong est comme un charme.
Mais configurer mPopupWindow.setFocusable (false). supprime le contact inutile nécessaire pour faire disparaître la fenêtre contextuelle.
Par exemple: Considérons qu’une fenêtre contextuelle est visible à l’écran et que vous êtes sur le point de cliquer sur un bouton. Donc, dans ce cas, (si mpopwindow.setFocusable (true)) Lors du premier clic sur un bouton, popupwindow disparaîtra. Mais vous devez cliquer à nouveau pour que le bouton fonctionne. if ** (mpopwindwo.setFocusable (false) ** clic simple du bouton ferme la fenêtre contextuelle et déclenche le clic du bouton. J'espère que cela aidera.
Dans certains cas, il n'est pas souhaitable de pouvoir mettre au point la fenêtre contextuelle (par exemple, vous ne voudrez peut-être pas qu'elle vole la mise au point dans une autre vue).
Une autre approche consiste à utiliser un intercepteur tactile:
popupWindow.setOutsideTouchable(true);
popupWindow.setTouchInterceptor(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_OUTSIDE) {
popupWindow.dismiss();
}
return false;
}
});
popupWindow.setTouchable(true);
popupWindow.setFocusable(true);
popupWindow.showAtLocation(popupView, Gravity.CENTER, 0, 0);
La fenêtre PopupWindow disparaîtra lorsque vous cliquerez/toucherez à l'écran. Assurez-vous que vous avez défini focusable sur true avant showAtLocation.
Vous pouvez utiliser isOutsideTouchable
OUisFocusable
pour masquer la fenêtre contextuelle lorsque vous touchez l'extérieur
popupWindow.isOutsideTouchable = true // dismiss popupwindow when touch outside
popupWindow.isFocusable = true // dismiss popupwindow when touch outside AND when press back button
Note
Actuellement, après le test, je vois setBackgroundDrawable
ne pas nous aider à rejeter popupwindow
Si vous regardez le code de licenciement dans PopupWindow
(PopupWindow->PopupDecorView->dispatchKeyEvent
et PopupWindow->PopupDecorView->onTouchEvent
). Vous verrez que lorsque vous appuierez sur le bouton Précédent, ils seront renvoyés sur ACTION_UP
et lorsqu'ils toucheront à l'extérieur, ils seront exclus sur ACTION_UP
ou ACTION_OUTSIDE
.
Utilisez View popupView pour fermer la popupWindow
`popupView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
popupWindow.dismiss();
}
});
` Si vous utilisez cette option, vous pouvez également définir OnLinkListener sur n’importe quel bouton de la fenêtre popup.