PopupWindow - 在外部点击时关闭

lor*_*tol 86 android popupwindow android-menu

我的活动中有一个PopupWindow,即使我正在与我的活动交互(比如在我的列表上滚动),我的PopupWindow仍会显示.我可以滚动浏览我的列表,PopupWindow仍在那里.

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

我试过setOutsideTouchable(true)但它不会解雇窗口.谢谢.

Mar*_* S. 124

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

  • 而已!thnx男人!在这种情况下,甚至可以正确处理触摸事件.popupWindow.setOutsideTouchable(真); popupWindow.setTouchable(真); popupWindow.setBackgroundDrawable(new BitmapDrawable()); popupWindow.setTouchInterceptor(new OnTouchListener(){@Override public boolean onTouch(View v,MotionEvent event){if(AppContext.isDebugMode())Log.d("POPUP_WINDOW","v:"+ v.getTag()+" | event:"+ event.getAction()); popupWindow.dismiss(); return true;}}); (29认同)
  • 我错过了.你在popupWindow上使用setBackgroundDrawable吗?我知道将drawable背景设置为null可以杀死OnTouchListener (5认同)
  • 将drawable背景设置为null对我不起作用.如果其他人有问题,请参阅我的回答. (3认同)
  • @WareNinja`DitmapDrawable()`被删除.请改用ColorDrawable()`. (3认同)
  • @WareNinja,您的评论有效!也许你最好把整个问题留给这个问题,这对其他人来说会很有用 (2认同)

mpe*_*egr 121

我发现所提供的答案都没有给我工作,除了WareNinja对接受的答案的评论,而Marcin S.的评论可能也会奏效.这是适合我的部分:

myPopupWindow.setBackgroundDrawable(new BitmapDrawable());
myPopupWindow.setOutsideTouchable(true);
Run Code Online (Sandbox Code Playgroud)

或者:

myPopupWindow.setFocusable(true);
Run Code Online (Sandbox Code Playgroud)

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

  • 非常感谢.其他答案都没有为我工作或解释得很好.第二种选择对我不起作用. (5认同)
  • 第一个解决方案有效,但第二个实际上没有. (3认同)
  • 另外我注意到BitmapDrawable已被弃用.有一个真正的问题解决方案会很好,因为这些看起来像临时解决方法并不能保证在较新的API版本中得到支持. (2认同)

Lun*_*ong 53

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

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

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

玩得开心@.@

  • 请务必在显示您的 popoupWindow 之前添加此代码 (3认同)

Mar*_* S. 23

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

现在为弹出窗口创建布局: 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>      
Run Code Online (Sandbox Code Playgroud)

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

final PopupWindow popupWindow = new PopupWindow(this);
popupWindow.show(findViewById(R.id.YOUR_MAIN_LAYOUT), 0, -250);
Run Code Online (Sandbox Code Playgroud)

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


Ngu*_*Dat 13

感谢@ 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));
Run Code Online (Sandbox Code Playgroud)

Mttdat.


too*_*o42 6

对于一ListPopupWindow组,显示时该窗口为模态窗口。

mListPopupWindow.setModal(true);
Run Code Online (Sandbox Code Playgroud)

这样,在的外部单击即可ListPopupWindow将其关闭。


Had*_*ote 6

请注意,对于取消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);
Run Code Online (Sandbox Code Playgroud)


Muh*_*Ali 5

mPopWindow.setFocusable(true);
Run Code Online (Sandbox Code Playgroud)


and*_*oid 5

  popupWindow.setTouchable(true);
  popupWindow.setFocusable(true);
  popupWindow.showAtLocation(popupView, Gravity.CENTER, 0, 0);
Run Code Online (Sandbox Code Playgroud)

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


Pha*_*inh 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
Run Code Online (Sandbox Code Playgroud)

笔记

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

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