我在我的活动中有一个PopupWindow,问题是即使我与我的活动交互(比如滚动列表),PopupWindow仍然显示。我可以滚动列表而PopupWindow仍然存在。
我想实现的是,当我触摸/滚动/点击等与PopupWindow不相关的屏幕时,我想关闭PopupWindow。就像菜单一样工作。如果你点击菜单外面,菜单就会被关闭。
我尝试过使用setOutsideTouchable(true)
,但它无法关闭窗口。谢谢。
我在我的活动中有一个PopupWindow,问题是即使我与我的活动交互(比如滚动列表),PopupWindow仍然显示。我可以滚动列表而PopupWindow仍然存在。
我想实现的是,当我触摸/滚动/点击等与PopupWindow不相关的屏幕时,我想关闭PopupWindow。就像菜单一样工作。如果你点击菜单外面,菜单就会被关闭。
我尝试过使用setOutsideTouchable(true)
,但它无法关闭窗口。谢谢。
我发现除了WareNinja在已被接受的答案中的评论和Marcin S.提供的答案可能也适用外,其他答案对我都不起作用。以下是对我有效的部分:
myPopupWindow.setBackgroundDrawable(new BitmapDrawable());
myPopupWindow.setOutsideTouchable(true);
或者:
myPopupWindow.setFocusable(true);
不确定它们之间的区别是什么,但是ListPopupWindow源代码在使用setModal将其模态设置为true时实际上使用了后者,因此至少Android开发人员认为这是一种可行的方法,且只需一行代码。
PopupWindow
上设置setBackgroundDrawable
,这样当您在窗口外部触摸时,它应该会关闭。BitmapDrawable()
已经过时,请使用ColorDrawable()
代替。 - Srujan Barai我遇到了相同的问题,按照以下代码进行了修复。这对我来说很有效。
// Closes the popup window when touch outside.
mPopupWindow.setOutsideTouchable(true);
mPopupWindow.setFocusable(true);
// Removes default background.
mPopupWindow.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
顺便提一下,不要使用BitmapDrawable的过时构造函数,使用new ColorDrawable(android.R.color.transparent)来替换默认背景。
祝你玩得愉快@.@
我知道现在已经很晚了,但我注意到人们仍然在使用弹出窗口时会遇到问题。因此,我决定写一个完全可用的示例,您可以通过点击窗口外部或窗口本身来关闭弹出窗口。要做到这一点,请创建一个新的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。
感谢 @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.
对于 ListPopupWindow
,在显示时将窗口设置为模态。
mListPopupWindow.setModal(true);
这样,点击ListPopupWindow
之外的区域将会关闭它。
mListPopupWindow.setInputMethodMode(PopupWindow.INPUT_METHOD_NOT_NEEDED);
,以防止弹出窗口干扰屏幕键盘。 - Mr-IDEpopupWindow.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);
您可以使用isOutsideTouchable
或者isFocusable
来在触摸外部时关闭弹出窗口。
popupWindow.isOutsideTouchable = true // dismiss popupwindow when touch outside
popupWindow.isFocusable = true // dismiss popupwindow when touch outside AND when press back button
注意
目前,在测试后我发现setBackgroundDrawable
不能帮助我们关闭弹出窗口。
如果您查看PopupWindow
中dismiss的代码(PopupWindow->PopupDecorView->dispatchKeyEvent
和PopupWindow->PopupDecorView->onTouchEvent
)。您会发现当按下返回键时,它们在ACTION_UP
上关闭,当触摸外部时,它们在ACTION_UP
或ACTION_OUTSIDE
上关闭。
popupWindow.setTouchable(true);
popupWindow.setFocusable(true);
popupWindow.showAtLocation(popupView, Gravity.CENTER, 0, 0);
mPopWindow.setFocusable(true);
BitmapDrawable()
已经过时,请使用ColorDrawable()
代替。 - Srujan Barai