107

我的活动中有一个 PopupWindow,问题是我的 PopupWindow 仍然显示,即使我正在与我的活动交互(比如在我的列表上滚动)。我可以滚动浏览我的列表并且 PopupWindow 仍然存在。

我想要实现的是当我在不是 PopupWindow 的屏幕上触摸/滚动/单击/等时,我想关闭 PopupWindow。就像菜单的工作原理一样。如果您在菜单外单击,菜单将被关闭。

我试过setOutsideTouchable(true)了,但它不会关闭窗口。谢谢。

4

15 回答 15

138

如果您触摸它的外部,请尝试设置setBackgroundDrawablePopupWindow应该关闭窗口。

于 2012-09-02T01:31:43.827 回答
132

我发现除了 WareNinja 对已接受答案的评论之外,提供的任何答案都不适合我,而 Marcin S. 的可能也适用。这是对我有用的部分:

myPopupWindow.setBackgroundDrawable(new BitmapDrawable());
myPopupWindow.setOutsideTouchable(true);

或者:

myPopupWindow.setFocusable(true);

不知道有什么区别,但是 ListPopupWindow 源代码实际上在使用 setModal 将其模态设置为 true 时使用后者,因此至少 Android 开发人员认为这是一种可行的方法,而且只有一行。

于 2013-07-31T15:31:55.450 回答
67

我遇到了同样的问题,并将其修复为以下代码。这对我来说可以。

    // Closes the popup window when touch outside.
    mPopupWindow.setOutsideTouchable(true);
    mPopupWindow.setFocusable(true);
    // Removes default background.
    mPopupWindow.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));

顺便说一句,不要使用 BitmapDrawable 已弃用的构造函数,使用这个新的 ColorDrawable(android.R.color.transparent)替换默认背景。

玩得开心@。@

于 2015-06-03T02:22:04.920 回答
25

我知道已经很晚了,但我注意到人们仍然对弹出窗口有疑问。我决定编写一个完整的工作示例,您可以通过触摸或单击弹出窗口外部或仅触摸窗口本身来关闭弹出窗口。为此,创建一个新的 PopupWindow 类并复制以下代码:

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);
   }
}

现在为弹出窗口创建布局: 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>      

在您的主要活动中创建 PopupWindow 类的实例:

final PopupWindow popupWindow = new PopupWindow(this);
popupWindow.show(findViewById(R.id.YOUR_MAIN_LAYOUT), 0, -250);

其中 YOUR_MAIN_LAYOUT 是 popupWindow 将在其中弹出的当前活动的布局

于 2012-09-29T19:01:16.033 回答
17

感谢@LunaKong 的回答和@HourGlass 的确认。我不想做重复的评论,只想说清楚简洁。

// 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));

月票。

于 2017-11-14T08:51:59.237 回答
9

对于ListPopupWindow将窗口设置为显示时的模式。

mListPopupWindow.setModal(true);

这样,在外部单击ListPopupWindow将关闭它。

于 2014-08-05T18:22:01.923 回答
7

请注意,要取消popupWindow.setOutsideTouchable(true),您需要wrap_content像下面的代码一样制作宽度和高度:

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);
于 2017-08-06T07:12:42.960 回答
5
mPopWindow.setFocusable(true);
于 2013-09-27T06:11:30.803 回答
5
  popupWindow.setTouchable(true);
  popupWindow.setFocusable(true);
  popupWindow.showAtLocation(popupView, Gravity.CENTER, 0, 0);

当单击/触摸屏幕时,它将关闭 PopupWindow。确保在 showAtLocation 之前设置了可聚焦的 true。

于 2017-07-31T06:21:54.443 回答
5

触摸外部时,您可以使用isOutsideTouchable OR isFocusable关闭弹出窗口

popupWindow.isOutsideTouchable = true // dismiss popupwindow when touch outside

popupWindow.isFocusable = true // dismiss popupwindow when touch outside AND when press back button

笔记

  • 目前,经过测试,我看到setBackgroundDrawable 不要帮助我们关闭 popupwindow

  • 如果您查看PopupWindow(PopupWindow->PopupDecorView->dispatchKeyEventPopupWindow->PopupDecorView->onTouchEvent) 中的关闭代码。您会看到,当按下后退按钮时,它们会关闭ACTION_UP,当触摸外部时,它们会关闭ACTION_UPACTION_OUTSIDE

于 2019-07-18T02:22:09.170 回答
4

@LunaKong 建议工作就像一个魅力。

但是设置mPopupWindow.setFocusable(false)。消除使弹出窗口消失所需的不必要的触摸。

例如:假设屏幕上有一个可见的弹出窗口,并且您将要单击一个按钮。因此,在这种情况下,(如果 mpopwindow.setFocusable(true))在第一次单击按钮 popupwindow 时将关闭。但是您必须再次单击才能使按钮起作用。if**(mpopwindwo.setFocusable(false)** 单击按钮关闭弹出窗口并触发按钮单击。 希望对您有所帮助。

于 2015-09-25T10:07:07.783 回答
3

设置窗口背景透明:

PopupWindow.getBackground().setAlpha(0);

在布局中设置背景之后。工作正常。

于 2014-02-17T10:08:44.137 回答
3

在某些情况下,使弹出窗口具有焦点是不可取的(例如,您可能不希望它从另一个视图中窃取焦点)。

另一种方法是使用触摸拦截器:

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;
    }
});
于 2017-08-09T10:02:13.797 回答
1

如果此弹出窗口是另一个活动,并且您将其大小减小到原始屏幕并且您想要启用或禁用外部区域。您可以通过以下代码简单地启用或禁用外部区域:

使能够:

YourActivity.this.setFinishOnTouchOutside(true);

禁用:

YourActivity.this.setFinishOnTouchOutside(false);

于 2020-08-28T14:45:59.267 回答
0

使用 View popupView 关闭 popupWindow

`popupView.setOnClickListener(new View.OnClickListener() {
                   @Override
                   public void onClick(View view) {
                       popupWindow.dismiss();
                   }
               }); 

` 如果你使用它,你还可以将 OnClickListener 设置为 popupWindow 内的任何按钮

于 2018-07-20T09:07:39.477 回答