打开弹出窗口并让外部仍然可触摸

6
如何在Android上打开PopupWindow并使其他所有组件可触摸,而不要关闭PopupWindow?
这是它的创建方式:
public class DynamicPopup {
    private final PopupWindow window;
    private final RectF rect;
    private final View parent;
    private final RichPageView view;

    public DynamicPopup(Context context, RichPage page, RectF rectF, View parent) {
        this.parent = parent;
        rect = rectF;

        window = new PopupWindow(context);

        window.setBackgroundDrawable(new BitmapDrawable());
        window.setWidth((int) rect.width());
        window.setHeight((int) rect.height());
        window.setTouchable(true);
        window.setFocusable(true);
        window.setOutsideTouchable(true);

        view = new RichPageView(context, page, false);
        window.setContentView(view);

        view.setOnCloseListener(new Listener(){
            @Override
            public void onAction() {
                window.dismiss();
            }
        });


    }

    public void show() {
        window.showAtLocation(parent, Gravity.NO_GRAVITY, (int) rect.left, (int) rect.top);
    }
}

2
你尝试过这个方法吗?http://developer.android.com/reference/android/widget/PopupWindow.html#setOutsideTouchable%28boolean%29 - ernazm
@ernazm,你应该将这个移到回答中。 - Phil
我不确定这种方法是否按预期工作,因为我没有使用过它(Android SDK 有很多错误的东西,说实话),并且这个问题已经被提出。 - ernazm
我已经添加了我正在使用的代码,但setOutsideTouchable(true)也不起作用。 - Marcos Vasconcelos
4个回答

12

就像ernazm所说的那样

根据javadocs

控制弹出窗口是否会被通知其窗口外的触摸事件。这仅适用于可触摸但无法聚焦的弹出窗口。

并且它适用于

window.setTouchable(true);
window.setFocusable(false);
window.setOutsideTouchable(false);

当 touchable 为 true,而 focusable 为 false 时,setOutsideTouchable() 会生效,如果设置 setOutsideTouchable(true),点击弹出窗口外部将会关闭弹出窗口,否则在不关闭弹出窗口的情况下仍然可以点击弹出窗口之外的区域。


1
setTouchable()默认为true,而setOutsideTouchable()默认为false。因此,您真正需要设置的是setFocusable(false)。但是,当弹出窗口不可聚焦时,似乎无法在其中的视图上工作事件监听器。 - string.Empty
有点棘手。文档是正确的,但出于某种原因,我总是想将focusable设置为true。上述三个设置都有效。 - Todd Painton
我的Spinner事件监听器可以工作,但我的EditText事件监听器无法工作。 - tony gil

8
根据Java文档,此属性控制弹出窗口是否会收到其窗口外的触摸事件通知。这仅适用于可触摸但无法聚焦的弹出窗口。
因此,您的代码行应为:
 window.setFocusable(true);

导致setOutsideTouchable()方法不起作用。


即使使用window.setFocusable(false);,此窗口仍会默认关闭。 - Marcos Vasconcelos

1

为此,您需要创建自定义弹出窗口。在其中,您需要调用另一个布局。这样,您就可以访问其他组件。 这只是一种类型的布局。但是,您可以将其外观设置为弹出窗口。

<!-- POPUP MENU -->
    <RelativeLayout 
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/popup_window"
        android:orientation="vertical"
        android:gravity="center"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:background="@drawable/fullwindowborderforpopup"
        >



        <LinearLayout

            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical"

            android:padding="1px"
            android:layout_marginTop="15dip"
            android:layout_marginLeft="20dip"
            android:layout_marginRight="20dip"
            android:layout_marginBottom="10dip"
            android:background="@drawable/borderforpopup"
            >
            <LinearLayout
                xmlns:android="http://schemas.android.com/apk/res/android"
                android:orientation="vertical" 
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:gravity="center_horizontal"
                android:layout_marginTop="5dip"
                android:layout_marginLeft="3dip"
                android:layout_marginRight="3dip"
                android:layout_marginBottom="3dip">

                <TextView 
                    android:id="@+id/tital_of_popup"
                    android:gravity="center_vertical|center_horizontal" 
                    android:layout_height="wrap_content" 
                    android:layout_width="wrap_content"
                    android:text="Event Registration"
                    android:textStyle="bold"
                    android:textColor="#ffffff" 
                    />
            </LinearLayout>

            <LinearLayout
                xmlns:android="http://schemas.android.com/apk/res/android"
                android:orientation="vertical" 
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:gravity="center_horizontal"
                android:layout_marginTop="5dip"
                android:layout_marginLeft="3dip"
                android:layout_marginRight="3dip"
                android:layout_marginBottom="3dip"
            >

                <TextView 
                    android:id="@+id/message_of_popup"
                    android:gravity="center_vertical|center_horizontal" 
                    android:layout_height="wrap_content" 
                    android:text="Please fill all the data" 
                    android:layout_width="wrap_content"
                    android:textStyle="normal"
                    android:textColor="#ffffff" />
        </LinearLayout>
        <LinearLayout
            xmlns:android="http://schemas.android.com/apk/res/android"
            android:orientation="vertical" 
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:gravity="center_horizontal"
            android:layout_marginTop="5dip"
            android:layout_marginLeft="6dip"
            android:layout_marginRight="6dip"
            android:layout_marginBottom="9dip"
                >


             <Button 
                android:layout_height="fill_parent" 
                android:id="@+id/okbutton" 
                android:text="OK" 
                android:textColor="#ffffff"
                android:shadowColor="#000000"
                android:gravity="center" 
                android:layout_width="fill_parent"
                android:background="@drawable/buttonborderframe"/>
        </LinearLayout>
    </LinearLayout>
</RelativeLayout>

试试这个。您可以在需要时隐藏和显示布局,而其他字段也是可访问的。


我真的需要在运行时添加PopupWindows,因为在运行之前我没有它们。 - Marcos Vasconcelos
1
然后,您需要为弹出窗口实现自定义样式,并根据您的需求设置属性。 - Shreyash Mahajan

0

尝试将以下代码添加到您的程序中:

window.setOutsideTouchable(true);

来自Android文档

void setOutsideTouchable (boolean touchable)

Controls whether the pop-up will be informed of touch events outside of its window. This only makes sense for pop-ups that are touchable but not focusable, which means touches outside of the window will be delivered to the window behind. The default is false.

If the popup is showing, calling this method will take effect only the next time the popup is shown or through a manual call to one of the update() methods.


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接