Android 实现顶层窗口、浮动窗口(附Demo)

  作过Window程序开发的朋友应该都知道,咱们要把程序窗口置顶很简单,只要设置一些窗口属性便可。可是到了Android,你没法简单设置一个属性,就让Android的Activity置顶。由于只要有新的Activity启动,你的Activity界面就会被挡住。今天介绍一下如何把一个窗口置顶。html

  也许会有人说:你的窗口置顶了,就会破坏系统的稳定性,影响其余程序使用,这是流氓行为o(╯□╰)o 。对于这个问题,若是你的顶层窗口没有处理好,的确会有这个问题。不过对于一些定制系统来讲,这个功能能够实现颇有用的功能,例如:对于一些须要长时间提示用户的危险警告。例以下面效果图,在浏览图片的时候,系统弹出一个警告框,会一直提示用户注意安全,就算切换到其余程序,这个提示框也会一直在顶层。安全

 

(PS:新建的QQ群,有兴趣能够加入一块儿讨论:Android群:322599434)布局

 

一、WindowManager介绍spa

  所有Android的窗口机制是基于一个叫作WindowManager实现,这个接口能够添加view到屏幕,也能够从屏幕删除view。它面向的对象一端是屏幕,另外一端就是View,直接忽视咱们之前的Activity或者Dialog之类的元素。其实咱们的Activity或者Diolog底层的实现也是通过WindowManager,WindowManager是全局的,整个系统只有一个WindowManager。它是显示View的最底层了。WindowManager主要用来管理窗口的一些状态、属性、view增长、删除、更新、窗口顺序、消息收集和处理等。经过Context.getSystemService(Context.WINDOW_SERVICE)的方式能够得到WindowManager的实例.WindowManager继承自ViewManager,里面涉及到窗口管理的三个重要方法,分别是3d

  • 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)code

而且打开会话(IWindowSession),以后Window将经过该会话与WindowManager创建联系。orm

 

 

二、使用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 = 100; params.height = 100; // 设置悬浮窗的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。例以下面的代码:htm


//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配置界面同样。 

 

三、注意事项

  在使用WindowManager的时候有一点须要注意的是,你只能把父节点的View添加到WindowManager里面,也就是说,你要添加的View不能是已经有父节点的某个子节点,不然会出现下面的问题:

 

四、结语

  上面就是建立一个顶层窗口或者浮动窗口的大体流程。之因此研究这个,我并非为了作浮动窗口,而是为了作浮动视频播放,这个下次有空,再写一篇如何作浮动视频播放的文章。

  最后补充一点,不要轻易使用全屏置顶的方法,由于这个会影响你系统其它程序的运行。特别是你的View设置为透明和全屏置顶,会致使界面没法操做。

 

给出一个浮动窗口的DemoFloating_window2013-8-7.rar

 

Edited by mythou

原创博文,转载请标明出处:http://www.cnblogs.com/mythou/p/3244208.html 

相关文章
相关标签/搜索