PopupWindow踩坑解决方案

在我们开发App的过程中,难免会有需求涉及到PopupWindow的使用。

最基本的创建方式:

 window = new PopupWindow(contentView, 
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT, true);

最后一个参数为boolean类型,即设置PopupWindow焦点,与PopupWindow的setFocusable(focusable)方法等同。

设置为true时,PopupWindow会处理事件。设置为false时,PopupWindow不获取焦点,事件上传到Activity。

所以,当设置为false时,点击返回键,PopupWindow不会隐藏,Activity会直接退出。

一般情况下,我们都会将其设置为true。

使用PopupWIndow时的情景状态又会分为两种情况:

(1)显示PopupWindow,点击内容区域以外的地方时,PopupWindow不隐藏。

(2)显示PopupWindow,点击内容区域以外的地方时,PopupWindow隐藏。

关于设置内容区域以外的点击状态,从PopupWindow源码中可以看到,PopupWindow为我们提供了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 {@link #update()} methods.


     *
     * @param touchable true if the popup should receive outside
     * touch events, false otherwise
     *
     * @see #isOutsideTouchable()
     * @see #isShowing()
     * @see #update()
     */  

  public void setOutsideTouchable(boolean touchable) {
        mOutsideTouchable = touchable;
    }

此时,我们来实现第一种情景:即点击,PopupWindow不隐藏:

window.setOutsideTouchable(false);
window.setBackgroundDrawable(null);

setBackgroundDrawable设置为null时,PopupWindow的单击和Key事件都不能起作用。此时问题来了,在点击返回键时,没有任何反应。PopupWindow不能关闭。

解决办法:

设置contentView,即PopupWindow的contentView:

contentView.setFocusable(true);
contentView.setFocusableInTouchMode(true);
contentView.setOnKeyListener(new OnKeyListener() {

@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if(keyCode == KeyEvent.KEYCODE_BACK) {
window.dismiss();
return true;
}
return false;
}
});


为PopupWindow的内容View添加Key的监听事件,当为返回键时,让PopupWindow隐藏。ok,完美解决!

第二种情景:

window.setOutsideTouchable(true);
window.setBackgroundDrawable(new ColorDrawable(0x000000));

setBackgroundDrawable设置了一个背景,此时PopupWindow的外部单击和key事件都会起作用(原理就是当我们设置了背景时,PopupWindow源码中会生成一个FrameLayout布局,同时为该布局添加单击和key事件)。

所以,此时点击内容区域外部时,PopupWindow会消失,并且点击返回键,PopupWindow也会消失。

希望你在平常的项目中使用的666!

你可能感兴趣的:(Android)