【转】android悬浮窗口
通过WindowManager的addView()方法,并设置WindowManager.LayoutParams的相关属性,就可以往WindowManager中加入所需要的View,而根据WindowManager.LayoutParams属性不同,也就能实现不同的效果。比如创建系统顶级窗口,实现悬浮窗口效果。如果需要将View从WindowManager中移除,只需要调用removeView()即可。
下面以一个简单的例子来解释一下如何实现悬浮窗口效果。
首先,得到WindoeManager对象:
WindowManager wManager = getApplicationContext().getSystemService( Context. WINDOW_ SERVICE);
其次,得到WindowManager.LayoutParams对象,为后续设置相关参数做准备:
private WindowManager.LayoutParams wmParams=new WindowManager.LayoutParams();
接着,设置相关的窗口布局参数,要实现悬浮窗口效果,主要需要设置的参数有:
wmParams.type = LayoutParams.TYPE_PHONE; // 设置window type
                   wmParams.format = PixelFormat.RGBA_8888; // 设置图片格式,效果为背景透明
        /*         
* 下面的flags属性的效果形同“锁定”。 悬浮窗不可触摸,不接受任何事件,同时不影响后面的事件响应。
*/
wmParams.flags=LayoutParams.FLAG_NOT_TOUCH_MODAL |
LayoutParams.FLAG_NOT_FOCUSABLE | LayoutParams.FLAG_NOT_TOUCHABLE;
wmParams.gravity = Gravity.RIGHT| Gravity. CENTER_VERTICAL; // 调整悬浮窗口至右侧中间
// 以屏幕左上角为原点,设置x、y初始值
wmParams.x = 0;
wmParams.y = 0;
// 设置悬浮窗口长宽数据
wmParams.width = WindowManager.LayoutParams.WRAP_CONTENT;;
wmParams.height =WindowManager.LayoutParams.WRAP_CONTENT;;
然后,就可以将需要加到悬浮窗口中的View加入到窗口中了:
if(view.getParent==null)//如果view没有被加入到某个父组件中,则加入WindowManager中
wManager.addView(view,wmParams);
其中,view为需要放到悬浮窗口中的视图组件。
如果要将其从WindowManager中移除,则可以执行以下语句:
if(view.getParent()!=null)
wManager.removeView(view);
最后,还有需要注意的是,如果要用悬浮窗口,需要在AndroidManifest.xml中加入如下的权限:
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
下面是一个具体的实例:
1 package net.xsmile.fv; 2 3 4 import android.app.Application; 5 import android.view.WindowManager; 6 7 8 public class MyApplication extends Application { 9 10 /** 11 * 创建全局变量 12 * 全局变量一般都比较倾向于创建一个单独的数据类文件,并使用static静态变量 13 * 14 * 这里使用了在Application中添加数据的方法实现全局变量 15 * 注意在AndroidManifest.xml中的Application节点添加android:name=".MyApplication"属性 16 * 17 */ 18 private WindowManager.LayoutParams wmParams=new WindowManager.LayoutParams(); 19 20 21 public WindowManager.LayoutParams getMywmParams(){ 22 return wmParams; 23 } 24 }
1 package net.xsmile.fv; 2 3 import android.content.Context; 4 import android.util.Log; 5 import android.view.MotionEvent; 6 import android.view.WindowManager; 7 import android.widget.ImageView; 8 9 public class MyFloatView extends ImageView { 10 private float mTouchStartX; 11 private float mTouchStartY; 12 private float x; 13 private float y; 14 15 16 private WindowManager wm=(WindowManager)getContext().getApplicationContext().getSystemService("window"); 17 18 //此wmParams为获取的全局变量,用以保存悬浮窗口的属性 19 private WindowManager.LayoutParams wmParams = ((MyApplication)getContext().getApplicationContext()).getMywmParams(); 20 21 public MyFloatView(Context context) { 22 super(context); 23 // TODO Auto-generated constructor stub 24 } 25 26 @Override 27 public boolean onTouchEvent(MotionEvent event) { 28 29 30 //获取相对屏幕的坐标,即以屏幕左上角为原点 31 x = event.getRawX(); 32 y = event.getRawY()-25; //25是系统状态栏的高度 33 Log.i("currP", "currX"+x+"====currY"+y); 34 switch (event.getAction()) { 35 case MotionEvent.ACTION_DOWN: 36 //获取相对View的坐标,即以此View左上角为原点 37 mTouchStartX = event.getX(); 38 mTouchStartY = event.getY(); 39 40 Log.i("startP", "startX"+mTouchStartX+"====startY"+mTouchStartY); 41 42 break; 43 case MotionEvent.ACTION_MOVE: 44 updateViewPosition(); 45 break; 46 47 case MotionEvent.ACTION_UP: 48 updateViewPosition(); 49 mTouchStartX=mTouchStartY=0; 50 break; 51 } 52 return true; 53 } 54 55 private void updateViewPosition(){ 56 //更新浮动窗口位置参数 57 wmParams.x=(int)( x-mTouchStartX); 58 wmParams.y=(int) (y-mTouchStartY); 59 wm.updateViewLayout(this, wmParams); 60 61 } 62 63 }
1 package net.xsmile.fv; 2 3 import android.app.Activity; 4 import android.graphics.PixelFormat; 5 import android.os.Bundle; 6 import android.view.Gravity; 7 import android.view.WindowManager; 8 import android.view.WindowManager.LayoutParams; 9 10 public class MyFloatViewActivity extends Activity { 11 /** Called when the activity is first created. */ 12 13 private WindowManager wm=null; 14 private WindowManager.LayoutParams wmParams=null; 15 16 private MyFloatView myFV=null; 17 18 19 @Override 20 public void onCreate(Bundle savedInstanceState) { 21 super.onCreate(savedInstanceState); 22 setContentView(R.layout.main); 23 //创建悬浮窗口 24 createView(); 25 26 } 27 28 29 30 private void createView(){ 31 myFV=new MyFloatView(getApplicationContext()); 32 myFV.setImageResource(R.drawable.icon); 33 //获取WindowManager 34 wm=(WindowManager)getApplicationContext().getSystemService("window"); 35 //设置LayoutParams(全局变量)相关参数 36 wmParams = ((MyApplication)getApplication()).getMywmParams(); 37 38 /** 39 *以下都是WindowManager.LayoutParams的相关属性 40 * 具体用途可参考SDK文档 41 */ 42 wmParams.type=LayoutParams.TYPE_PHONE; //设置window type 43 wmParams.format=PixelFormat.RGBA_8888; //设置图片格式,效果为背景透明 44 45 //设置Window flag 46 wmParams.flags=LayoutParams.FLAG_NOT_TOUCH_MODAL 47 | LayoutParams.FLAG_NOT_FOCUSABLE; 48 /* 49 * 下面的flags属性的效果形同“锁定”。 50 * 悬浮窗不可触摸,不接受任何事件,同时不影响后面的事件响应。 51 wmParams.flags=LayoutParams.FLAG_NOT_TOUCH_MODAL 52 | LayoutParams.FLAG_NOT_FOCUSABLE 53 | LayoutParams.FLAG_NOT_TOUCHABLE; 54 */ 55 56 57 wmParams.gravity=Gravity.LEFT|Gravity.TOP; //调整悬浮窗口至左上角 58 //以屏幕左上角为原点,设置x、y初始值 59 wmParams.x=0; 60 wmParams.y=0; 61 62 //设置悬浮窗口长宽数据 63 wmParams.width=40; 64 wmParams.height=40; 65 66 //显示myFloatView图像 67 wm.addView(myFV, wmParams); 68 69 } 70 71 @Override 72 public void onDestroy(){ 73 super.onDestroy(); 74 //在程序退出(Activity销毁)时销毁悬浮窗口 75 wm.removeView(myFV); 76 } 77 78 79 80 }
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="net.xsmile.fv" android:versionCode="1" android:versionName="1.0"> <application android:name=".MyApplication" android:icon="@drawable/icon" android:label="@string/app_name"> <activity android:name=".MyFloatViewActivity" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" /> </manifest>
 
                    
                     
                    
                 
                    
                
 
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号