zoukankan      html  css  js  c++  java
  • WindowManager实现悬浮窗口&可自由移动的悬浮窗口

    Android标题栏进度指示器使用

    比如Android自带的浏览器在载入网页时等待时间可能会在标题栏的右上角有一个小圆圈在不断旋转,由于其不包含具体进度,很多网友可能没有找到详细的操作方法在SDK中。作为标题栏进度指示器其实属于Activity类的方法。

      在使用时我们首先需要在setContentView之前声明 requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS); ,在需要显示进度时调用 setProgressBarIndeterminateVisibility(true);即可,停止时调用 setProgressBarIndeterminateVisibility(false);



    WindowManager实现悬浮窗口&可自由移动的悬浮窗口  


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

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

    而WindowManager.LayoutParams的属性就多了,非常丰富,具体请查看SDK文档。这里给出Android中的WindowManager.java源码,可以具体看一下。 
    WindowManager 的源码地址: 
    http://www.netmite.com/android/mydroid/frameworks/base/core/java/android/view/WindowManager.java 

    以下代码请仅供演示:

    Java代码  收藏代码
    1. public class myFloatView extends Activity {  
    2.     /** Called when the activity is first created. */  
    3.     @Override  
    4.     public void onCreate(Bundle savedInstanceState) {  
    5.         super.onCreate(savedInstanceState);  
    6.         setContentView(R.layout.main);  
    7.         Button bb=new Button(getApplicationContext());  
    8.         WindowManager wm=(WindowManager)getApplicationContext().getSystemService("window");  
    9.         WindowManager.LayoutParams wmParams = new WindowManager.LayoutParams();  
    10.         wmParams.type=2002;  //type是关键,这里的2002表示系统级窗口,你也可以试试2003。  
    11.         wmParams.format=1;  
    12.         /** 
    13.          *这里的flags也很关键 
    14.          *代码实际是wmParams.flags |= FLAG_NOT_FOCUSABLE; 
    15.          *40的由来是wmParams的默认属性(32)+ FLAG_NOT_FOCUSABLE(8) 
    16.          */  
    17.         wmParams.flags=40;  
    18.         wmParams.width=40;  
    19.         wmParams.height=40;  
    20.         wm.addView(bb, wmParams);//创建View  
    21.     }  
    22. }  


    PS:本代码在Android2.3下测试无错(从API Level来看,实际上android1.5都可行)!另外别忘了在AndroidManifest.xml文件中加入如下权限:

     
    Xml代码  收藏代码
    1. <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />  



    关于代码中wmParams.type的值的问题,下面给出一些数值参考: 
    /** 
             * Window type: the status bar.  There can be only one status bar 
             * window; it is placed at the top of the screen, and all other 
             * windows are shifted down so they are below it. 
             */ 
            public static final int TYPE_STATUS_BAR         = FIRST_SYSTEM_WINDOW; 
        
            /** 
             * Window type: the search bar.  There can be only one search bar 
             * window; it is placed at the top of the screen. 
             */ 
            public static final int TYPE_SEARCH_BAR         = FIRST_SYSTEM_WINDOW+1; 
        
            /** 
             * 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; 
            
            /** 
             * Window type: keyguard window. 
             */ 
            public static final int TYPE_KEYGUARD           = FIRST_SYSTEM_WINDOW+4; 
            
            /** 
             * Window type: transient notifications. 
             */ 
            public static final int TYPE_TOAST              = FIRST_SYSTEM_WINDOW+5; 
            
            /** 
             * Window type: system overlay windows, which need to be displayed 
             * on top of everything else.  These windows must not take input 
             * focus, or they will interfere with the keyguard. 
             */ 
            public static final int TYPE_SYSTEM_OVERLAY     = FIRST_SYSTEM_WINDOW+6; 
            
            /** 
             * Window type: priority phone UI, which needs to be displayed even if 
             * the keyguard is active.  These windows must not take input 
             * focus, or they will interfere with the keyguard. 
             */ 
            public static final int TYPE_PRIORITY_PHONE     = FIRST_SYSTEM_WINDOW+7; 
            
            /** 
             * Window type: panel that slides out from the status bar 
             */ 
            public static final int TYPE_STATUS_BAR_PANEL   = FIRST_SYSTEM_WINDOW+8; 
            
            /** 
             * Window type: panel that slides out from the status bar 
             */ 
            public static final int TYPE_SYSTEM_DIALOG      = FIRST_SYSTEM_WINDOW+8; 
        
            /** 
             * Window type: dialogs that the keyguard shows 
             */ 
            public static final int TYPE_KEYGUARD_DIALOG    = FIRST_SYSTEM_WINDOW+9; 
            
            /** 
             * Window type: internal system error windows, appear on top of 
             * everything they can. 
             */ 
            public static final int TYPE_SYSTEM_ERROR       = FIRST_SYSTEM_WINDOW+10; 
            
            /** 
             * End of types of system windows. 
             */ 
            public static final int LAST_SYSTEM_WINDOW      = 2999; 

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

        可以看出来,2002的值的含义其实就是2000+2。数值2000的含义就是系统级窗口,2002和2003的区别就是 2003 比 2002还要更上一层!比如,type为2003的view,能显示在手机下拉状态栏之上! 

    而关于flags等其他的属性请参考SDK文档 

    Android悬浮窗体 
    http://www.xsmile.net/?p=396 
    Android中悬浮窗口的实现原理和示例代码 
    http://www.xsmile.net/?p=404 

    Android中可自由移动悬浮窗口的Demo 
    http://www.xsmile.net/?p=452 
    前段时间捣鼓出Android悬浮窗口的实现,今天抽空写了一个可自由移动悬浮窗口的Demo。 

    简要说明如下: 

    1、通过覆写悬浮View中onTouchEvent方法实现自由移动悬浮窗口。 

    2、悬浮窗口坐标的移动实际是windowMananager.LayoutParams中x和y的变换,但是要注意设置相应的gravity。 

    3、用windowManager创建的View,当不需要时,务必记住使用windowManager的removeView方法来移除,请在Activity相关生命周期中自行添加扫尾工作。 

    4、代码中已经附上详细注释。有关参数具体含义,请自行参考SDK。 

    =============================== 

    注意Demo中wmParams.format=1的属性(我源码中打了双斜杠),如果启用,图片背景将会透明,效果图如下: 


    ================================ 

    一些说明: 

    对于种种原因没有查看SDK文档的一些朋友,可能对我源码中wmParams.type=2002这样的语句不太了解其2002的具体意义,给出可读性好点的语句。 

    Java代码  收藏代码
    1. wmParams.type=LayoutParams.TYPE_PHONE;   
    2.        //wmParams.format=PixelFormat.RGBA_8888;   //设置图片格式,效果为背景透明  
    3.        wmParams.flags=LayoutParams.FLAG_NOT_TOUCH_MODAL  
    4.                              | LayoutParams.FLAG_NOT_FOCUSABLE;  
    5.        /* 
    6.         * 下面的flags属性的效果形同“锁定”。 
    7.         * 悬浮窗不可触摸,不接受任何事件,同时不影响后面的事件响应。 
    8.         wmParams.flags=LayoutParams.FLAG_NOT_TOUCH_MODAL  
    9.                               | LayoutParams.FLAG_NOT_FOCUSABLE 
    10.                               | LayoutParams.FLAG_NOT_TOUCHABLE; 
    11.        */  



    附Demo源码: 

    Android中悬浮窗口 
    http://www.cnblogs.com/GnagWang/archive/2011/02/06/1949569.html 

  • 相关阅读:
    Java实现 LeetCode 394 字符串解码
    Java实现 LeetCode 394 字符串解码
    Java实现 LeetCode 392 判断子序列
    Java实现 LeetCode 392 判断子序列
    Java实现 LeetCode 392 判断子序列
    Java实现 LeetCode 391 完美矩形
    Java实现 LeetCode 391 完美矩形
    Java实现 LeetCode 391 完美矩形
    Java实现 LeetCode 390 消除游戏
    Java实现 LeetCode 390 消除游戏
  • 原文地址:https://www.cnblogs.com/new0801/p/6175920.html
Copyright © 2011-2022 走看看