博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
PopupWindow 点击外部区域无法关闭的问题
阅读量:6854 次
发布时间:2019-06-26

本文共 3042 字,大约阅读时间需要 10 分钟。

[TOC] 在android4.0/5.0系统上,使用popupWindow时,点击内容外部区域无法关闭,但是在6.0机子上又是正常的,而我在代码中明明已经进行了如下设置:

mPopupWindow = new PopupWindow(popView, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT, true);// 点击其他地方消失mPopupWindow.setOutsideTouchable(true);复制代码

google了一下都说要添加一句:

mPopupWindow.setBackgroundDrawable(new BitmapDrawable());复制代码

测试了果然ok,不过还是想知道下所以然,稍微探究一下: 既然是点击没效果,搜索一下touch事件好了: 在4.0/5.0的 PopupWindow.java 源码中发现是在 PopupViewContainer 类中设置的,而在6.0源码中则是位于 PopupDecorView 类;

继续查找在哪里初始化的,发现 preparePopup(),它是在显示(showAtLocation() , showAsDropDown())的时候调用的,而 preparePopup() 的具体内容:

// PopupWindow.java @ api 14/19/21private void preparePopup(WindowManager.LayoutParams p) {    if (mContentView == null || mContext == null || mWindowManager == null) {        throw new IllegalStateException("You must specify a valid content view by "                + "calling setContentView() before attempting to show the popup.");    }    if (mBackground != null) {        final ViewGroup.LayoutParams layoutParams = mContentView.getLayoutParams();        int height = ViewGroup.LayoutParams.MATCH_PARENT;        if (layoutParams != null &&                layoutParams.height == ViewGroup.LayoutParams.WRAP_CONTENT) {            height = ViewGroup.LayoutParams.WRAP_CONTENT;        }        // when a background is available, we embed the content view        // within another view that owns the background drawable        PopupViewContainer popupViewContainer = new PopupViewContainer(mContext);        PopupViewContainer.LayoutParams listParams = new PopupViewContainer.LayoutParams(                ViewGroup.LayoutParams.MATCH_PARENT, height        );        popupViewContainer.setBackgroundDrawable(mBackground);        popupViewContainer.addView(mContentView, listParams);        mPopupView = popupViewContainer;    } else {        mPopupView = mContentView;    }    mPopupWidth = p.width;    mPopupHeight = p.height;}复制代码

这里可以看到当background不为null的时候,在contentView外面套了一层PopupViewContainer,而PopupViewContainer中才有关于touch,key的监听事件,因此若未设置背景,则点击外部区域无法取消popupwindow,即使设置了:

mPopupWindow.setOutsideTouchable(true);复制代码

而在android6.0中:

// PopupWindow.java @ api 23private void preparePopup(WindowManager.LayoutParams p) {    ......    // When a background is available, we embed the content view within    // another view that owns the background drawable.    if (mBackground != null) {        mBackgroundView = createBackgroundView(mContentView);        mBackgroundView.setBackground(mBackground);    } else {        mBackgroundView = mContentView;    }    // 无论background是否为空,都会创建decorView,它是PopupDecorView的实例,其实就是一个FrameLayout,里面有touch事件的监听,因此无需设置背景也可以点击外部区域取消popupwindow的    mDecorView = createDecorView(mBackgroundView);    ......}复制代码

总之,跟网友说的一致,添加背景图片就可以了:

Bitmap bmp = BitmapFactory.decodeResource(getContext().getResources(), R.drawable.bg_popup_window);Drawable drawable = new BitmapDrawable(getContext().getResources(), bmp);// 不带参的方法已经deprecatedpopupWindow.setBackgroundDrawable(drawable);复制代码

转载于:https://juejin.im/post/5a433b236fb9a0452725de50

你可能感兴趣的文章
python3编写网络爬虫17-验证码识别
查看>>
防XSS攻击
查看>>
形形色色的下拉菜单(特效菜单)
查看>>
C++ OpenSSL 之一:编译和使用
查看>>
Class.forName()的原理机制
查看>>
无网络联机打单机游戏---博客园老牛大讲堂
查看>>
#iOS问题记录#动态Html加载本地CSS和JS文件
查看>>
jquery事件之select选中事件
查看>>
IIS负载均衡之介绍篇:Application Request Route详解
查看>>
-webkit-overflow-scrolling
查看>>
钉钉开发系列(十一)钉钉网页扫码登录
查看>>
什么是ERP
查看>>
linux ./configure 的参数详解
查看>>
Github 上 Star 最多的个人 Spring Boot 开源学习项目
查看>>
企业级大数据平台构建
查看>>
0302作业.
查看>>
关于:target与定位动画的奇怪现象
查看>>
linq
查看>>
css设置height 100%
查看>>
数据结构与算法基本学习笔记(5)
查看>>