WindowManager可以在当前屏幕创造一个小窗口 并且可以加入拖动 同时又不影响当前屏幕的操作 形成一个悬浮窗口
常用方法及属性:
WindowManager:
1. windowManager.addView(参数1,参数2);
a) 参数1:要加入的布局View 一般是继承布局的类
b) 参数2:设定的窗体属性WindowManager.LayoutParams mwParams
2. windowManager.removeView(参数);
a) 参数:同上面的参数1 要删除的布局view类
WindowManager.LayoutParams:窗体属性
1. mwParams.type:窗口类型 用LayoutParams.类型属性 常用 LayoutParams.TYPE_PHONE,LayoutParams.TYPE_SYSTEM_ERROR
2. mwParams.format:作用不明 设定为1即可
3. mwParams.flags:主要设定窗口能否获取焦点等功能 通常加入LayoutParams.FLAG_NOT_TOUCH_MODAL| LayoutParams.FLAG_NOT_FOCUSABLE这两项
4. mwParams.width:数值或者WindowManager.LayoutParams.WRAP_CONTENT来设定
5. mwParams.height:数值或者WindowManager.LayoutParams.WRAP_CONTENT来设定
6. mwParams.gravity:设定窗口显示在屏幕的哪里 Gravity.LEFT | Gravity.TOP 这样设定是在屏幕的左上 不设定则显示在屏幕正中央
7. mwParams.x, mwParams.y:设定窗口出现的横纵坐标
操作流程:
1. 加入权限:<uses-permissionandroid:name="android.permission.SYSTEM_ALERT_WINDOW"/>
2. 创建XML布局文件就是浮动窗口要显示的内容
3. Activity:主要做启动Service或者停止Service的操作,以达到显示和隐藏浮动窗口
4.Service:在onStartCommand方法中调用已经创建好的WindowManager类中的创建悬浮窗方法
在onDestroy方法中调用WindowManager类中的删除窗口方法
5.WindowManager类:
createWindow:设定要创建的窗口各项属性并创建新的窗口
removeWindow:删除指定的窗口
6.FloatWindow View类:
这个类其实是继承布局的View,主要做一些UI操作 比如单击事件 拖动事件等
ps:要注意的是布局中绑定了监听事件的控件是无法拖动的,也就是不会执行ontouch.
执行顺序 1 2 6 5 4 3···
详细Demo见文件内Demo
特别注意在写拖动事件时有可能根据屏幕不同出现不同效果以下有两种一种不行就试另一种。
第一种:ontouch:
@Override
publicboolean onTouchEvent(MotionEvent event) {
switch(event.getAction()) {
caseMotionEvent.ACTION_DOWN:
//手指按下时记录必要数据,纵坐标的值都需要减去状态栏高度
xInView= event.getX();
yInView= event.getY();
xDownInScreen= event.getRawX();
yDownInScreen= event.getRawY() - 25;
xInScreen= event.getRawX();
yInScreen= event.getRawY() -25;
break;
caseMotionEvent.ACTION_MOVE:
xInScreen= event.getRawX();
yInScreen= event.getRawY() - 25;
//手指移动的时候更新小悬浮窗的位置
updateViewPosition();
break;
caseMotionEvent.ACTION_UP:
//如果手指离开屏幕时,xDownInScreen和xInScreen相等,且yDownInScreen和yInScreen相等,则视为触发了单击事件。
if(xDownInScreen == xInScreen && yDownInScreen == yInScreen) {
//openBigWindow();
}
break;
default:
break;
}
returntrue;
}
privatevoid updateViewPosition() {
mParams.x= (int) (xInScreen - xInView);
mParams.y= (int) (yInScreen - yInView);
windowManager.updateViewLayout(this,mParams);
}
第二种:
@Override
publicboolean onTouchEvent(MotionEvent event) {
switch(event.getAction()) {
caseMotionEvent.ACTION_DOWN:
xInScreen= (int) event.getRawX();
yInScreen= (int) event.getRawY();
xDownInScreen= mParams.x;
yDownInScreen= mParams.y;
break;
caseMotionEvent.ACTION_MOVE:
xInView= (int) (event.getRawX() - xInScreen);
yInView= (int) (event.getRawY() - yInScreen);
mParams.x = (int)(xDownInScreen - xInView);
mParams.y = (int)(yDownInScreen + yInView);
updateViewPosition();
break;
caseMotionEvent.ACTION_UP:
//如果手指离开屏幕时,xDownInScreen和xInScreen相等,且yDownInScreen和yInScreen相等,则视为触发了单击事件。
if(xDownInScreen == xInScreen && yDownInScreen == yInScreen) {
//openBigWindow();
}
break;
default:
break;
}
returntrue;
}
privatevoid updateViewPosition() {
windowManager.updateViewLayout(this,mParams);
}
以上是本人参考网上例子(都不能运行)做了一个简易例子 大家可以添加更多的内容 做的复杂点
源代码下载地址:http://download.csdn.net/detail/a85454597/7560693
代码中在注册service时包名没写完全 请大家自己修改一下 否则可能导致无法打开悬浮窗