教育行業(yè)A股IPO第一股(股票代碼 003032)

全國(guó)咨詢/投訴熱線:400-618-4000

Android培訓(xùn)之WindowManager的使用

更新時(shí)間:2016年07月23日15時(shí)11分 來(lái)源:Android培訓(xùn)學(xué)員 瀏覽次數(shù):

1. WindowManager,Window的介紹

1.1. Window

Window表示一個(gè)窗口。對(duì)于Android里的Window,我們可以類比Windows系統(tǒng)中的Window,在Windows中,每打開(kāi)一個(gè)軟件,都會(huì)彈出一個(gè)窗口,這個(gè)窗口右上角有最小化,最大化,關(guān)閉按鈕,做了某些操作時(shí),也可能會(huì)彈出一個(gè)窗口,下面可能會(huì)有確定,取消之類的按鈕,這些都是Windows系統(tǒng)中的窗口。如圖所示:


Android中所有的界面都是顯示在一個(gè)個(gè)Window中的,包括Activity,Dialog,Toast,甚至狀態(tài)欄,最近應(yīng)用列表,都是在Window中顯示的。只是我們看不到這些Window的邊框,只能看到里面的內(nèi)容。其實(shí) Window并不能真正的顯示內(nèi)容,它只是一個(gè)虛擬的"框",真正能顯示內(nèi)容的是View。Window是View的直接管理者,觸摸事件也是先由Window接收,然后傳遞給View的。
Window是一個(gè)抽象類,在Android手機(jī)中,Window的實(shí)現(xiàn)類是PhoneWindow。

1.2. WindowManager

WindowManager是Window的管理者,對(duì)應(yīng)著系統(tǒng)底層的一個(gè)服務(wù):WindowManagerService。
我們無(wú)法直接訪問(wèn)Window,要操作Window,必須通過(guò)WindowManager。WindowManager有三個(gè)常用方法:addView,removeView,updateViewLayout我們可以通過(guò)WindowManager往屏幕上添加/刪除一個(gè)Window,或者通過(guò)它修改一個(gè)Window的布局參數(shù)。
WindowManager是一個(gè)接口,在Android中,WindowManager的實(shí)現(xiàn)類WindowManagerImpl。

2. WindowManager使用詳解

2.1. 往屏幕上添加一個(gè)Window

調(diào)用WindowManager的addView方法即可。

顯示效果如下:

2.2. 代碼詳解

上面的代碼表示:調(diào)用 WindowManager的 addView(View view,WindowManager。LayoutParams lp) 方法,往屏幕上添加一個(gè)Window,這個(gè)Window中顯示的內(nèi)容為第一個(gè)參數(shù)設(shè)置的View,Window的顯示位置以及其他屬性由第二個(gè)參數(shù) WindowManager。LayoutParams指定。
這個(gè)方法很簡(jiǎn)單,但是 WindowManager。LayoutParams 中有兩個(gè)字段比較重要,這里詳細(xì)說(shuō)一下。
1.flags
用來(lái)控制Window的顯示特性,有很多可取的值,不同的的值表示不同的顯示特性, 如果希望Window具有多個(gè)值的特性, 可以使用 “|” 將這些值進(jìn)行按位或運(yùn)算。這里介紹幾個(gè)比較常用的取值:

2.type
用來(lái)表示W(wǎng)indow的類型,Window有三種大的類型,分別是應(yīng)用Window,子Window和系統(tǒng)Window。Activity的Window就是一種應(yīng)用Window,Dialog的Window是一種子Window,子Window不能單獨(dú)存在,必須附屬在特定的父Window中,這也就是為什么Dialog的Context必須是Activity。系統(tǒng)Window大都是(不是全部)需要聲明權(quán)限才能創(chuàng)建,獨(dú)立應(yīng)用Window之外,比如Toast,狀態(tài)欄等等。
Window是分層的,層級(jí)大的會(huì)覆蓋在層級(jí)小的之上,三大類Window中,應(yīng)用Window層級(jí)范圍是1-99,子Window是1000-1999,系統(tǒng)Window是2000-2999,這就是為什么Dialog顯示在Activity之上,而Toast又可以顯示在Dialog之上。如圖:


 
type這個(gè)字段的取值有很多,不同的值表示不同的層級(jí)范圍,具體可以看文檔,一般來(lái)說(shuō),如果這個(gè)取值為系統(tǒng)Window層級(jí)范圍內(nèi)的值,則需要聲明權(quán)限:
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
另外,type會(huì)影響flags的效果,比如,如果type設(shè)置為 TYPE_TOAST,則無(wú)論怎樣設(shè)置flags,這個(gè)Window都無(wú)法接收觸摸事件。

2.3. 查看屏幕上的Window

我們?cè)偻聊簧霞右粋€(gè)PopupWindow和一個(gè)Dialog,當(dāng)前界面如下:

在Eclipse中,點(diǎn)擊菜單 Window - Open Perspective - Others,選擇 HierarchyView,打開(kāi),選擇Windows面板,可以看到當(dāng)前屏幕中所有的Window:

我們添加的Window在其中顯示的標(biāo)題為AddWindow,另外,我們可以看到還有別的幾個(gè)Window,比如 PopupWindow,MainActivity,加粗的那一個(gè)其實(shí)是MainActivity中彈出的Dialog,還能看到 StatusBar(狀態(tài)欄),RecentsPanel(最近應(yīng)用列表)等等,這也證明了我們前面說(shuō)的,Android中所有的界面都是顯示在Window中的。

3桌面懸浮窗實(shí)現(xiàn)思路

3.1. 在桌面上顯示W(wǎng)indow

如果我們?cè)贏ctivity中使用WindowManager添加Window,當(dāng)Activity退出時(shí),添加的Window也會(huì)被回收掉。所以要想在桌面上顯示懸浮窗,可以在Service中使用WindowManager添加Window,這樣只要服務(wù)不停止,就可以一直顯示。當(dāng)服務(wù)啟動(dòng)時(shí),在其onCreate方法中,使用WindowManager的 addView方法添加一個(gè)系統(tǒng)Window,當(dāng)服務(wù)銷毀時(shí),可以在其 onDestroy中使用WindowManager的removeView 方法移除Window。大體是這樣的思路,代碼就不再給出了。

3.2.. 讓這個(gè)Window隨手指移動(dòng)

要想讓這個(gè)Window能接收事件,需要給他設(shè)置相應(yīng)的flags(只要不包含F(xiàn)LAG_NOT_TOUCHABLE即可),另外其type也不能是 TYPE_TOAST??梢允褂茫篢YPE_PRIORITY_PHONE,表示比來(lái)去電界面的Window級(jí)別還要高一些(來(lái)去電界面的Window是系統(tǒng)Window)。

注意添加權(quán)限:

 然后給Window里的View設(shè)置onTouchListener,重寫(xiě)onTouch方法:

這樣就實(shí)現(xiàn)了Window隨著手指拖動(dòng)而移動(dòng)了。

 本文版權(quán)歸傳智播客Android培訓(xùn)學(xué)院所有,歡迎轉(zhuǎn)載,轉(zhuǎn)載請(qǐng)注明作者出處。謝謝!
作者:傳智播客Android培訓(xùn)學(xué)院
首發(fā):http://oisangadgets.com/Android
0 分享到:
和我們?cè)诰€交談!