1. 程式人生 > >Window和WindowManager的簡介和使用

Window和WindowManager的簡介和使用

在某些特殊的時候,我們需要在桌面建立一個類似懸浮窗的東西,這種效果就需要用到Window來實現,Window是一個抽象的概念,它的具體實現是PhoneWindow。建立一個Window只需要通過WindowManager即可完成。WindowManager是外界訪問Window的入口,Window的具體實現在WindowManagerService中,WindowManager和WindowManagerService的互動是一個IPC的過程。Android所有的檢視都是通過Window來呈現的,不管是ACtivity,Dialog還是Toast,他們的檢視實際上都是附加在Window上的,因此,Window實際是View的直接管理者。View的事件分發機制,從Window傳遞給DecorView,再由DecorView 傳遞給我們的View,Activity設定檢視的方法setContentView()的方法也是在Window實現的

1.用WindowManager新增一個Window

mLayourParams = new WindowManager.LayoutParams(WindowManager.LayoutParams.WRAP_CONTENT,
        WindowManager.LayoutParams.WRAP_CONTENT, 0, 0, PixelFormat.TRANSPARENT);
mLayourParams.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
        | WindowManager.LayoutParams
.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED; mLayourParams.gravity = Gravity.LEFT | Gravity.TOP; mLayourParams.x = 100; mLayourParams.y = 300; mWinManager = getWindowManager(); mWinManager.addView(view, mLayourParams);

WindowManager.LayoutParam中的flag和type比較重要

Flags引數標示Window的屬性,三種常用的
(1)FLAG_NOT_FOCUSABLE 這種 模式的Window不需要獲取焦點,也不需要接收各種輸入事件,此標記會同時啟動(2),事件最終會傳遞給下層具有焦點的Window
(2)FLAG_NOT_TOUCH_MODEL 系統會將Window區域外的單擊事件傳遞給底層的Window,當前WIndow區域的單擊事件自己處理,一般都需要開啟此標記,不然其他Window將無法接收到點選事件
(3)FLAG_SHOW_WHEN_LOCKED 可以讓Window顯示在鎖屏的介面上

Type引數標示Window的型別:
1.應用Window,應用類Window對應著一個Activity。
2.子Window ,子Window不能單獨存在,它需要附屬在特定的父Window之中,比如常見的Dialog就是一個子Window。
3.系統Window,是需要宣告許可權才能建立的Window,比如Toast和系統狀態列這些都是系統的Window

Window是分層級的,層級大的會覆蓋在層級小的上面,應用Window的層級是1-99.子Window的層級是1000-1999,系統Window的層級是2000-2999

mLayourParams.type= WindowManager.LayoutParams.TYPE_SYSTEM_ERROR;
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>

WindowManager提供了三個方法,addView(),updataViewLayout(),removeView()

view.setOnTouchListener(new View.OnTouchListener()
{
    @Override
    public boolean onTouch(View v, MotionEvent event)
    {
        int rawX = (int) event.getRawX();
        int rawY = (int) event.getRawY();
        switch (event.getAction())
        {
            case MotionEvent.ACTION_MOVE:
                mLayourParams.x = rawX;
                mLayourParams.y = rawY;
                mWinManager.updateViewLayout(view, mLayourParams);
                break;
            default:
                break;

        }
        return false;
    }
});