xsmile
You can fly higher
xsmile's Blog
Android中悬浮窗口的实现原理和示例代码

用了我一个周末的时间,个中愤懑就不说了,就这个问题,我翻遍全球网络没有一篇像样的资料,现在将实现原理简单叙述如下:

调用WindowManager,并设置WindowManager.LayoutParams的相关属性,通过WindowManager的addView方法创建View,这样产生出来的View根据WindowManager.LayoutParams属性不同,效果也就不同了。比如创建系统顶级窗口,实现悬浮窗口效果!

WindowManager的方法很简单,基本用到的就三个addView,removeView,updateViewLayout。

而WindowManager.LayoutParams的属性就多了,非常丰富,具体请查看SDK文档。这里给出Android中的WindowManager.java源码,可以具体看一下

下面是简单示例代码:

public class myFloatView extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        Button bb=new Button(getApplicationContext());
        WindowManager wm=(WindowManager)getApplicationContext().getSystemService("window");
        WindowManager.LayoutParams wmParams = new WindowManager.LayoutParams();

        /**
         *以下都是WindowManager.LayoutParams的相关属性
         * 具体用途请参考SDK文档
         */
        wmParams.type=2002;   //这里是关键,你也可以试试2003
        wmParams.format=1;
         /**
         *这里的flags也很关键
         *代码实际是wmParams.flags |= FLAG_NOT_FOCUSABLE;
         *40的由来是wmParams的默认属性(32)+ FLAG_NOT_FOCUSABLE(8)
         */
        wmParams.flags=40;
        wmParams.width=40;
        wmParams.height=40;
        wm.addView(bb, wmParams);  //创建View
    }
}

别忘了在AndroidManifest.xml中添加权限:

PS:这里举例说明一下type的值的意思:

        /**
         * Window type: phone.  These are non-application windows providing
         * user interaction with the phone (in particular incoming calls).
         * These windows are normally placed above all applications, but behind
         * the status bar.
         */
        public static final int TYPE_PHONE              = FIRST_SYSTEM_WINDOW+2;

        /**
         * Window type: system window, such as low power alert. These windows
         * are always on top of application windows.
         */
        public static final int TYPE_SYSTEM_ALERT       = FIRST_SYSTEM_WINDOW+3;

这个FIRST_SYSTEM_WINDOW的值就是2000。2003和2002的区别就在于2003类型的View比2002类型的还要top,能显示在系统下拉状态栏之上!

————————————————————————————-

已经给出可自由移动悬浮窗口的Demo,参加这里

首页      技术      Android      Android中悬浮窗口的实现原理和示例代码

发表回复

textsms
account_circle
email

  • figofuture

    hi 我试了下TYPE_SYSTEM_ALERT这种类型的window,也不能悬浮在status bar之上啊,兄弟有没有什么新发现?

    14 年前 回复
    • @figofuture: @figofuture 

      饿~我的意思是能显示在“系统下拉状态栏”(通知区域)之上,关于显示在status bar上,我也不知道…如果有人发现了麻烦说一下,呵呵…

      14 年前 回复
  • xzy

    哈哈,霸气啊

    12 年前 回复
  • xzy

    “就这个问题,我翻遍全球网络没有一篇像样的资料”

    哈哈,霸气啊

    12 年前 回复
  • Good

    12 年前 回复
  • 碧水青山

    大神,能否把完整的源码给我发一份?想学习一下,谢谢!

    12 年前 回复
  • 匿名

    wmParams.flags=40;

    这样写,真是无言以对。

    11 年前 回复
    • xsmile博主

      @匿名: 哈哈哈,后面的示例代码改成常量了~

      wmParams.flags=LayoutParams.FLAG_NOT_TOUCH_MODAL
      | LayoutParams.FLAG_NOT_FOCUSABLE;

      参看这篇http://www.xsmile.net/?p=538

      11 年前 回复
  • song

    Thanks a lot ~

    11 年前 回复
  • hlm

    樓主,很有用, 十分感謝
    但這個是否可以設置wmParams 來變成悬浮在activity 之內?
    另外, 如何在 MyFloatView 加設 onclick listener 或 drag listener 呢?
    我是android 新手, 問題可能很蠢, 但麻煩樓指導一下, 感謝!!

    11 年前 回复

xsmile's Blog

Android中悬浮窗口的实现原理和示例代码
用了我一个周末的时间,个中愤懑就不说了,就这个问题,我翻遍全球网络没有一篇像样的资料,现在将实现原理简单叙述如下: 调用WindowManager,并设置WindowManager.LayoutParams的相关…
扫描二维码继续阅读
2011-01-24