Android 实现顶层窗口、浮动窗口(附Demo)
做过Window程序开发的朋友应该都知道,我们要把程序窗口置顶很简单,只要设置一些窗口属性即可。但是到了Android,你无法简单设置一个属性,就让Android的Activity置顶。因为只要有新的Activity启动,你的Activity界面就会被挡住。今天介绍一下如何把一个窗口置顶。
也许会有人说:你的窗口置顶了,就会破坏系统的稳定性,影响其他程序使用,这是流氓行为o(╯□╰)o 。对于这个问题,如果你的顶层窗口没有处理好,的确会有这个问题。不过对于一些定制系统来说,这个功能可以实现很有用的功能,例如:对于一些需要长时间提示用户的危险警告。例如下面效果图,在浏览图片的时候,系统弹出一个警告框,会一直提示用户注意安全,就算切换到其他程序,这个提示框也会一直在顶层。

(PS:新建的QQ群,有兴趣可以加入一起讨论:Android群:322599434)
1、WindowManager介绍
全部Android的窗口机制是基于一个叫做WindowManager实现,这个接口可以添加view到屏幕,也可以从屏幕删除view。它面向的对象一端是屏幕,另一端就是View,直接忽视我们以前的Activity或者Dialog之类的元素。其实我们的Activity或者Diolog底层的实现也是经过WindowManager,WindowManager是全局的,整个系统只有一个WindowManager。它是显示View的最底层了。WindowManager主要用来管理窗口的一些状态、属性、view增加、删除、更新、窗口顺序、消息收集和处理等。通过Context.getSystemService(Context.WINDOW_SERVICE)的方式可以获得WindowManager的实例.WindowManager继承自ViewManager,里面涉及到窗口管理的三个重要方法,分别是
- addView();
- updateViewLayout();
- removeView();
在WindowManager中还有一个重要的静态类LayoutParams。通过它可以设置和获得当前窗口的一些属性。我们先来看看addView()方法,在addView中,会利用LayoutParams获得window的View属性,并为每个window创ViewRoot,ViewRoot是View和WindowManager之间的桥梁,真正把View传递给WindowManager的是通过ViewRoot的setView()方法,ViewRoot实现了View和WindowManager之间的消息传递。在将主窗口添加到WindowManger时,它首先会建立一个代理对象:
wm=(WindowManagerImpl)context.getSystemService(Context.WINDOW_SERVICE)
并且打开会话(IWindowSession),之后Window将通过该会话与WindowManager建立联系。
2、使用WindowManager实现浮动窗口
//Edited by mythou
//http://www.cnblogs.com/mythou/
private void createFloatView()
{
Button btn_floatView = new Button()
btn_floatView = new Button(getApplicationContext());
btn_floatView.setText("悬浮窗"); wm = (WindowManager) getApplicationContext().getSystemService(
Context.WINDOW_SERVICE);
params = new WindowManager.LayoutParams(); // 设置window type
params.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
/*
* 如果设置为params.type = WindowManager.LayoutParams.TYPE_PHONE; 那么优先级会降低一些,
* 即拉下通知栏不可见
*/ params.format = PixelFormat.RGBA_8888; // 设置图片格式,效果为背景透明 // 设置Window flag
params.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
| WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
/*
* 下面的flags属性的效果形同“锁定”。 悬浮窗不可触摸,不接受任何事件,同时不影响后面的事件响应。
* wmParams.flags=LayoutParams.FLAG_NOT_TOUCH_MODAL |
* LayoutParams.FLAG_NOT_FOCUSABLE | LayoutParams.FLAG_NOT_TOUCHABLE;
*/ // 设置悬浮窗的长得宽
params.width = ;
params.height = ; // 设置悬浮窗的Touch监听
btn_floatView.setOnTouchListener(new OnTouchListener()
{
int lastX, lastY;
int paramX, paramY; public boolean onTouch(View v, MotionEvent event)
{
switch (event.getAction())
{
case MotionEvent.ACTION_DOWN:
lastX = (int) event.getRawX();
lastY = (int) event.getRawY();
paramX = params.x;
paramY = params.y;
break;
case MotionEvent.ACTION_MOVE:
int dx = (int) event.getRawX() - lastX;
int dy = (int) event.getRawY() - lastY;
params.x = paramX + dx;
params.y = paramY + dy;
// 更新悬浮窗位置
wm.updateViewLayout(btn_floatView, params);
break;
}
return true;
}
}); wm.addView(btn_floatView, params);
isAdded = true;
}
上面是一段创建一个浮动窗口的代码,主要就是使用了WindowManager的addView方法,把我们创建的一个View添加到WindowManager里面去。除了使用上面的代码动态创建一个View,我们也可以直接加载某个XML文件,然后生成一个View,我们平常使用的XML布局文件解析完,都是能生成一个View对象,因此我们可以直接编写一个布局文件然后使用LayoutInflater来加载对应的View。例如下面的代码:
//Edited by mythou
//http://www.cnblogs.com/mythou/
LayoutInflater inflater = LayoutInflater.from(getApplicationContext());
//加载需要的XML布局文件
RelativeLayout mInView = (RelativeLayout)inflater.inflate(R.layout.in_vedio, null, false); //......
//添加到WindowManager里面
wm.addView(btn_floatView, params);
如果需要实现一个全屏置顶的窗口,只要编写一个全屏的XML配置文件即可,跟我们在Activity里面使用的XML配置界面一样。
3、注意事项
在使用WindowManager的时候有一点需要注意的是,你只能把父节点的View添加到WindowManager里面,也就是说,你要添加的View不能是已经有父节点的某个子节点,否则会出现下面的问题:

4、结语
上面就是创建一个顶层窗口或者浮动窗口的大致流程。之所以研究这个,我并不是为了做浮动窗口,而是为了做浮动视频播放,这个下次有空,再写一篇如何做浮动视频播放的文章。
最后补充一点,不要轻易使用全屏置顶的方法,因为这个会影响你系统其它程序的运行。特别是你的View设置为透明和全屏置顶,会导致界面无法操作。
给出一个浮动窗口的Demo:Floating_window2013-8-7.rar
Edited by mythou
原创博文,转载请标明出处:http://www.cnblogs.com/mythou/p/3244208.html
Android 实现顶层窗口、浮动窗口(附Demo)的更多相关文章
- (转)Android 仿订单出票效果 (附DEMO)
之前我下载了BaseAnimation 开源库(BaseAnimation是基于开源的APP,致力于收集各种动画效果) BaseAnimation 转载的链接:http://blog.csdn.net ...
- Android浮动窗口的实现
1.浮动窗口的实现原理 看到上图的那个小Android图标了吧,它不会被其他组建遮挡,也可以响应用户的点击和拖动事件,它的显示和消失由WindowManager直接管理,它就是Android浮动窗口. ...
- Android 浮动窗口进阶——画中画,浮动视频(附Demo)
今天继续上一篇Android顶层窗口.浮动窗口的进阶应用.上一篇主要讲解了WindowManager服务和如何使用WindowManager编写一个顶层窗口.今天主要是讲讲如何在顶层窗口里面播放视频, ...
- Android Studio 工具窗口浮动与布局恢复【申明:来源于网络】
Android Studio 工具窗口浮动与布局恢复[申明:来源于网络] http://bbs.chinaunix.net/thread-4182438-1-1.html
- Android Studio 使用笔记:工具窗口浮动与布局恢复
Android Studio 的工具窗口都可以变成浮动窗口,如果有多个显示器的话,这种模式非常方便.方法如下: 然后就像下图那样,可以拖拽了.如果你不小心关了,没有关系.再次点击工具栏,浮动窗口就回显 ...
- Jquery 类似新浪微博,鼠标移到头像,用浮动窗口显示用户信息,已做成一个jquery插件
请注意!!!!! 该插件demo PHP 的 demo下载 C#.NET的demo下载 需要如下图, 1.鼠标移动到头像DIV时,Ajax获取数据,并让浮动DIV显示出来. 2.鼠标可以移动到上面浮 ...
- Android 浮窗开发之窗口层级
很多人都知道如何去实现一个简单的浮窗,但是却很少有人去深入的研究背后的流程机制,由于项目中浮窗交互比较复杂,遇到了些坑查看了很多资料,故总结浮窗涉及到的知识点: 窗口层级关系(浮窗是如何"浮 ...
- (转)JS浮动窗口(随浏览器滚动而滚动)
原文:http://hi.baidu.com/aiyayaztt/item/4201c55a6b729dced2e10c79 JS浮动窗口(随浏览器滚动而滚动) 往往用于一些联系方式,互动平台模块,随 ...
- Delphi 悬浮窗口、浮动窗口的实现
源:Delphi 悬浮窗口.浮动窗口的实现 浮动窗体的实现 http://blog.tianya.cn/blogger/post_show.asp?BlogID=68097&PostID=80 ...
随机推荐
- ImportError: cannot import name cbook
Faster RCNN训练的时候,出现错误: from matplotlib import path, transforms File , in <module> from . impor ...
- metasploit常见服务的漏点扫描模块
弱点扫描 根据信息收集结果搜索漏洞利用模块 结合外部漏洞扫描系统对大IP地址段进行批量扫描 可以考虑对单个ip,单个服务进行扫描 NVC 密码破解端口:5900use auxiliary/scanne ...
- 利用zabbix监控oracle数据库
一.概述 zabbix是一款非常强大,同时也是应用最为广泛的开源监控软件,本文将给大家介绍如何利用zabbix监控oracle数据库. 二.环境介绍 以下是我安装的环境,实际部署时并不需要跟我的环境一 ...
- Java设计模式从精通到入门三 策略模式
介绍 我尽量用最少的语言解释总结: Java23种设计模式之一,属于行为型模式.一个类的行为或者算法可以在运行时更改,策略对象改变context对象执行算法. 应用实例: 以周瑜赔了夫人又折兵的例 ...
- [漏洞分析]thinkcmf 1.6.0版本从sql注入到任意代码执行
0x00 前言 该漏洞源于某真实案例,虽然攻击没有用到该漏洞,但在分析攻击之后对该版本的cmf审计之后发现了,也算是有点机遇巧合的味道,我没去找漏洞,漏洞找上了我XD thinkcmf 已经非常久远了 ...
- BZOJ.4566.[HAOI2016]找相同字符(后缀数组 单调栈)
题目链接 给定两个字符串,求它们有多少个相同子串.相同串的位置不同算多个. POJ3145简化版. 后缀自动机做法见这儿,又快又好写(一下就看出差距了..) //13712kb 4076ms #inc ...
- LED类代码
/* led.c文件 标题: 点亮一个了LED灯 电路:开发板中P2口已接到LED灯的阴极 */ #include <reg52.h> #include "led1.h&qu ...
- [HihoCoder1398]网络流五·最大权闭合子图
题目大意:有$N$项活动$M$个人,每个活动$act_i$有一个正的权值$a_i$,每个人$stu_i$有一个负的权值$b_i$.每项活动能够被完成当且仅当该项活动所需的所有人到场.如何选择活动使最终 ...
- memcached协议解析
本文转载自:http://www.ccvita.com/306.html 协议memcached 的客户端使用TCP链接与服务器通讯.(UDP接口也同样有效,参考后文的 “UDP协议” )一个运行中的 ...
- JavaScript_原型和继承(2017-03-15)
一.函数创建过程 在了解原型链之前我们先来看看一个函数在创建过程中做了哪些事情,举一个空函数的例子: function A() {}; 当我们在代码里面声明这么一个空函数,js解析的本质是(肤浅理解有 ...