Android开发学习之WindowManager实现弹窗
背景
我们知道PopupWindow可以实现弹窗,但是如果要实现系统弹窗(即悬浮在所有view、dialog之上),需要调用通过反射PopupWindow类的私有方法setWindowLayoutType()。但如果某个手机厂商的修改了Framework层,这种反射调用就失败了,因此如果要实现系统弹窗,需要另辟蹊径。
解决方法
解决方法就是使用WindowManager,及用来设置参数的WindowManager.LayoutParams
WindowManager mWindowManager = getWindowManager();WindowManager.LayoutParams mWindowLayoutParams = new WindowManager.LayoutParams();
加载弹窗根布局
mWindowView = (LinearLayout) LayoutInflater.from(this).inflate(R.layout.window_layout, null);
设置弹窗位置
mWindowLayoutParams.gravity = Gravity.START;mWindowLayoutParams.x = 0;mWindowLayoutParams.y = 0;
设置弹窗类型(系统浮窗)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {mWindowLayoutParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;} else {mWindowLayoutParams.type = WindowManager.LayoutParams.TYPE_PHONE;}
设置触摸事件穿透
mWindowLayoutParams.flags |= WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;mWindowLayoutParams.flags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;mWindowView.setOnTouchListener(new View.OnTouchListener() { // 事件坐标转换@Overridepublic boolean onTouch(View v, MotionEvent event) {int[] popupLocation = new int[2];mWindowView.getLocationOnScreen(popupLocation);event.offsetLocation(popupLocation[0], popupLocation[1]);MainActivity.this.dispatchTouchEvent(event);return false;}});
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL表示允许该弹窗外面的触摸事件发送到其下面的窗口,否则所有触摸事件都会发送到当前的弹窗窗口;
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE表示弹窗不获取焦点,因此该弹窗不会接收任何按钮或按键事件,对应的事件会传到其下面的窗口。
mWindowView是弹窗的根布局,当触摸事件从弹窗传到下面的activity时,需要进行坐标转换。
设置弹窗半透明
mWindowLayoutParams.format = PixelFormat.TRANSLUCENT;
设置弹窗尺寸
mWindowLayoutParams.height = 1800; // 单位是像素mWindowLayoutParams.width = WindowManager.LayoutParams.WRAP_CONTENT;
设置软键盘适配
mWindowLayoutParams.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
添加或移除view
@Overrideprotected void onStop() {super.onStop();mWindowManager.removeView(mWindowView); // 移除view}@Overrideprotected void onResume() {super.onResume();mWindowManager.addView(mWindowView, mWindowLayoutParams); // 添加view}
源码地址
参见gitlab仓库
Android开发学习之WindowManager实现弹窗相关推荐
- Android开发学习之以CameraAPI方式实现相机功能(一)——快速实现相机
今天无意当中发现在<Android开发学习之基于ZBar实现微信扫一扫>中的一部分代码可以用来以硬件方式实现一个照相机的功能,在<Android开发学习之调用系统相机完成拍照的实现& ...
- android培训内容明细,记录Android开发学习
记录Android开发学习 Menu菜单学习 1.掌握Android中菜单的创建. 2.掌握Intent信使组件. 创建菜单Menu 我们模仿微信菜单栏学习,创建一个于微信菜单栏相似的菜单 那么我们应 ...
- android开发学习之路——连连看之游戏逻辑(五)
GameService组件则是整个游戏逻辑实现的核心,而且GameService是一个可以复用的业务逻辑类. (一)定义GameService组件接口 根据前面程序对GameService组件的依赖, ...
- Android开发学习---使用Intelij idea 13.1 进行android 开发
Android开发学习---使用Intelij idea 13.1 进行android 开发 原文:Android开发学习---使用Intelij idea 13.1 进行android 开发 1.为 ...
- 《Java和Android开发学习指南(第2版)》—— 1.5 本章小结
本节书摘来异步社区<Java和Android开发学习指南(第2版)>一书中的第1章,第1.5节,作者:[加]Budi Kurniawan,更多章节内容可以访问云栖社区"异步社区& ...
- 《Java和Android开发学习指南(第2版)》——第2章,第2.10节本章小结
本节书摘来自异步社区<Java和Android开发学习指南(第2版)>一书中的第2章,第2.10节本章小结,作者 [加]Budi Kurniawan,更多章节内容可以访问云栖社区" ...
- Android开发学习之基于ViewPager实现Gallery画廊效果
通过我们前面的学习,我们知道ViewPager是可以做出近乎完美的滑动体验,回顾整个Android,我们发现Gallery具备同样的特点,于是我们大胆地猜想,Gallery是否和ViewPager之间 ...
- Android开发学习总结(四)——Eclipse在线安装ADT插件
Android开发学习总结(四)--Eclipse在线安装ADT插件 要想使用Eclipse开发Android应用,首先要安装一个ADT插件,在此记录一下在Eclipse中采用在线安装的方式ADT插件 ...
- android开发用百度识别图片格式,Android开发学习之路-机器学习库(图像识别)、百度翻译...
对于机器学习也不是了解的很深入,今天无意中在GitHub看到一个star的比较多的库,就用着试一试,效果也还行.比是可能比不上TensorFlow的,但是在Android上用起来比较简单,毕竟Tens ...
最新文章
- GitHub霸榜项目:30万字图解算法题典,超全实用资源,狂揽6000星
- android把255转换成字节,android 上传参数设置,字符转化成字节,包装流等
- 二分图的最大带权匹配
- Python计算本周是第几周
- mysql主主同步配置_MySQL 主主同步配置步骤
- Depth-first Search深度优先搜索专题7
- javascript sort排序
- 商业认知,近期与部分中小创业者一起吃饭,忽然有人谈到现在创业越来越难
- 超过 C++、压制 Java 与 C,Python 拔得 TIOBE 年度编程语言!
- 基础 - 常见字符的ASCII码
- (原创)使用nRF51822/nRF51422创建一个简单的BLE应用 ---入门实例手册(中文)之五...
- A_A03_001 stc-isp 单片机烧录软件安装与使用
- 学习笔记(01):ThreeJS视频教程-了解着色器基础
- 如何学习IOS APP开发?开发iOS手机软件一般用什么编程语言?
- 在IE地址栏显示自己的小图标
- mac电脑免费支持NTFS格式 mounty
- goback history 传递参数_goback 返回上一页触发刷新 / 回调传参
- excel怎么筛选?教你一个简单粗暴的筛选技巧
- VC通过ADO操作Access2007数据库
- [矩阵论] Unit 1. 线性空间与线性变换 - 知识点整理