Android PopupWindow - 在外面点击时关闭

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12232724/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 10:06:43  来源:igfitidea点击:

PopupWindow - Dismiss when clicked outside

androidpopupwindowandroid-menu

提问by villager

I have a PopupWindow on my activity, the thing is my PopupWindow still shows even when I'm interacting with my activity (say scrolling on my list). I can scroll through my list and the PopupWindow is still there.

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

What I want to achieve is when I'm touching/scrolling/clicking/etc on the screen which is not the PopupWindow, I want to dismiss the PopupWindow. Just like how a menu works. If you clicked outside of the menu, the menu will be dismissed.

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

I've tried setOutsideTouchable(true)but it won't dismiss the window. Thanks.

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

回答by Marcin S.

Please try to set setBackgroundDrawableon PopupWindowthat should close the window if you touch outside of it.

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

回答by mpellegr

I found that none of the answers supplied worked for me, except WareNinja's comment on the accepted answer, and Marcin S.'s will probably also work. Here's the part that works for me:

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

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

Alternatively:

或者:

myPopupWindow.setFocusable(true);

Not sure what the differences are, but the ListPopupWindow source code actually uses the latter when it's modality is set to true with setModal, so at least the Android developers consider this a viable approach, and it's only one line.

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

回答by Luna Kong

I met the same issues, and fixed it as below codes. It works fine for me.

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

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

BTW, Don't use BitmapDrawable deprecated constructor, use this new ColorDrawable(android.R.color.transparent)to replace default background.

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

Have fun@.@

玩得开心@。@

回答by Marcin S.

I know it's late but I notice that people still have an issue with the popup window. I have decided to write a fully working example where you can dismiss the popup window by touching or clicking outside of it or just touching the window itself. To do so create a new PopupWindow class and copy this code:

我知道已经晚了,但我注意到人们仍然对弹出窗口有问题。我决定编写一个完整的示例,您可以通过触摸或单击它的外部或仅触摸窗口本身来关闭弹出窗口。为此,创建一个新的 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);
   }
}

Now create the layout for the popup window: popup.xml

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

In your main activity create an instance of the PopupWindow class:

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

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

where YOUR_MAIN_LAYOUT is the layout of the current activity in which popupWindow will pop up

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

回答by Nguyen Tan Dat

Thanks for @LunaKong's answer and @HourGlass's confirmation. I don't want to make a duplicated comment, but only want to make it clear and concise.

感谢@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));

Mttdat.

日期。

回答by toobsco42

For a ListPopupWindowset the window to be a modal when shown.

对于一个ListPopupWindow组的窗口是一个模态所示,当。

mListPopupWindow.setModal(true);

That way, clicking outside of the ListPopupWindowwill dismiss it.

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

回答by Hadi Note

Notice that for canceling with popupWindow.setOutsideTouchable(true), you need to make width and height wrap_contentlike below code:

请注意,要取消 with 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);

回答by android

  popupWindow.setTouchable(true);
  popupWindow.setFocusable(true);
  popupWindow.showAtLocation(popupView, Gravity.CENTER, 0, 0);

It will dismiss the PopupWindow when click/touch on screen.Make sure you have set focusable true before showAtLocation.

当在屏幕上单击/触摸时,它将关闭 PopupWindow。确保在 showAtLocation 之前已将 focusable 设置为 true。

回答by Phan Van Linh

You can use isOutsideTouchableORisFocusableto dissmiss popup window when touch outside

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

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

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

Note

笔记

  • Currently, after test I see setBackgroundDrawabledon'thelp us dismiss popupwindow

  • If you look at the code for dismiss in PopupWindow(PopupWindow->PopupDecorView->dispatchKeyEventand PopupWindow->PopupDecorView->onTouchEvent). You will see that when press back button, they dismiss on ACTION_UPand when touch outside they dismiss on ACTION_UPor ACTION_OUTSIDE

  • 目前,经过测试,我发现setBackgroundDrawable并不能帮助我们解除弹出窗口

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

回答by HourGlass

@LunaKong suggestion work's like a charm.

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

But setting up mPopupWindow.setFocusable(false).removes unnecessary touch required to make popup window disappear.

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

For example: Let's consider there is a pop up window visible on screen, and you are about to click a button. So in this case, (if mpopwindow.setFocusable(true)) on the first click of a button popupwindow will dismiss. But you have to click again to make the button works. if**(mpopwindwo.setFocusable(false)** single click of button dismiss the popup window as well as trigger the button click.Hope it helps.

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