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事件,實時改變按鈕位置即可。