WindowManager添加悬浮窗
WindowManager是外界访问Window的入口,Window的具体实现位于WindowManagerService中,并且WindowManager和WindowManagerService交互是一个IPC过程。Window是View的直接管理者。
通过WindowManager添加一个Window:
final Button mButton = new Button(MainActivity.this);
mButton.setText("测试");
mButton.setTextColor(Color.BLACK);
final WindowManager windowManager = MainActivity.this.getWindowManager();
final LayoutParams params = new WindowManager.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, 0, 0, PixelFormat.TRANSPARENT);
params.flags = LayoutParams.FLAG_NOT_TOUCH_MODAL|LayoutParams.FLAG_NOT_FOCUSABLE|LayoutParams.FLAG_SHOW_WHEN_LOCKED;//flags 可以控制window的显示特性 FLAG_NOT_TOUCH_MODAL在此模式下,系统会将当前window区域以外的单击事件传递给底层的window,当前window区域以内单击事件自己处理。这个标记很重要,一般来说都需要开启此标记,否则其他window将无法收到单击事件。 FLAG_NOT_FOCUSABLE表示window不需要获取焦点,也不需要获取各种输入事件。FLAG_SHOW_WHEN_LOCKED 让window显示在锁屏界面上
params.gravity = Gravity.LEFT|Gravity.TOP;
params.x = 100;
params.y = 200;
params.type = LayoutParams.TYPE_SYSTEM_ERROR;//在三类window中,应用window的层级范围为1-99,子window的层级范围为1000-1999,系统window的层级范围是2000-2999,这些层级对应着type参数,一般如果使用系统type要记得加权限:android.permission.SYSTEM_ALERT_WINDOW
//params.type = WindowManager.LayoutParams.TYPE_TOAST;
windowManager.addView(mButton, params);
WindowManager提供了三个方法,添加、更新、删除View,分别为:
addView updateViewLayout removeView
要实现悬浮窗的拖拽效果和点击效果也很简单:
mButton.setOnTouchListener(new OnTouchListener() {
int lastX, lastY;
int paramX, paramY;
@Override
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;
Toast.makeText(getApplicationContext(), "点到我了", 0).show(); 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;
// 更新悬浮窗位置
windowManager.updateViewLayout(mButton, params);
break;
}
return true;
}
});
通过监听move事件,实时改变按钮位置即可。