像360懸浮窗那樣,用WindowManager實現(xiàn)炫酷的懸浮迷你音樂盒(上)

說到懸浮窗大家一定會想到這倆貨

打開簡信我的首頁腺劣,亮閃閃的幾個字6天之前绿贞,是的,距離我的上一篇文章已經(jīng)6天橘原,原計劃這篇文章會是在周一晚上的時候發(fā)的籍铁,可是最近也有點突發(fā)事件,打亂我原有的計劃趾断【苊咳!反正就是瞎忙芋酌,不過我還是會堅持用心寫好每一篇文章增显。

記得上一篇講的是用RotateDrawable實現(xiàn)網(wǎng)易云音樂唱片機(jī)效果,而今天我要講的是如何用WindowManager去實現(xiàn)一個懸浮窗迷你音樂盒脐帝。同云,由于WindowManager這一塊內(nèi)容會比較多,所以我決定分成上下兩篇來寫這一塊堵腹,這一篇主要介紹WindowManager和它的一些屬性炸站,可能會有些枯燥,下一篇我會具體去寫懸浮迷你音樂盒的實現(xiàn)疚顷。

WindowManager

在Android應(yīng)用開發(fā)中旱易,其實整個Android的窗口機(jī)制是基于一個叫做WindowManager的一個系統(tǒng)服務(wù)接口,WindowManager可以添加view到屏幕腿堤,也可以從屏幕刪除view咒唆。它面向的對象一端是屏幕,另一端就是View释液,其實就連我們常用的Activity和Diolog的底層實現(xiàn)都是通過WindowManager, WindowManager是全局的装处,整個系統(tǒng)就只用一個Windowmanager服務(wù)误债,我們需要向系統(tǒng)獲取服務(wù)才能調(diào)用它,而它就是顯示View的最底層妄迁。

其實WindowManager用起來非常方便寝蹈,就三個方法:

添加View
addView(View view, WindowManager.LayoutParams params);

從方法中我們可以看到,addView需要兩個參數(shù)登淘,view簡單箫老,就是我們要向窗口中去添加的對象,至于params黔州,就是給窗口設(shè)置的顯示策略耍鬓,包括窗口的大小阔籽、透明度等等,這個也是今天文章的重點牲蜀,在后文會有所介紹笆制。

移除View
removeView(View view);

既然能夠向窗口去添加View,當(dāng)然也就能夠從窗口上移除View涣达,這個很簡單view就是你要從窗口中移除的對象在辆。

刷新View
updateViewLayout(View view, ViewGroup.LayoutParams params)

同樣窗口刷新也需要兩個參數(shù),和添加View一樣view是需要更新的對象度苔,而params就是更新后的策略屬性匆篓。

WindowManager.LayoutParams

相比于WindowManager,WindowManager.LayoutParams可就要復(fù)雜好多了寇窑。WindowManager.LayoutParams是 WindowManager 接口的嵌套類鸦概,在窗口管理中扮演著重要的角色。它繼承于ViewGroup.LayoutParams疗认,它用于向WindowManager描述窗口的管理策略完残;WindowManager.LayoutParams可以直接new WindowManager.LayoutParams()新建,也可以從對窗口的getAttributes()得到其WindowManager.LayoutParams對象横漏。WindowManager.LayoutParams常用的有以下主要常量成員:

flag
  • WindowManager.LayoutParams.FLAG_SECURE 不允許截屏谨设;設(shè)置了這個屬性的窗口,在窗口可見的情況下缎浇,是會禁用系統(tǒng)的截圖功能的扎拣。那么問題來了:假如有一天,你的公司要求寫一個類似于‘閱后即焚’功能的頁面的話素跺,不妨在activity中獲得WindowManager.LayoutParams并添加該屬性二蓝,輕輕松松搞定。
  • WindowManager.LayoutParams.FLAG_BLUR_BEHIND 背景模糊指厌;假如你的窗口設(shè)置了這個屬性刊愚,并且這個窗口可見,在這窗口之后的所有背景都會被模糊化踩验,但我還沒有發(fā)現(xiàn)一個屬性是可以控制模糊程度的鸥诽。
  • WindowManager.LayoutParams.FLAG_DIM_BEHIND 背景變暗;設(shè)置這個效果的窗口箕憾,在窗口可見的情況下牡借,窗口后方的背景會相應(yīng)的變暗,這個屬性需要配合參數(shù)dimAmount一起使用袭异,dimAmount會在后文中介紹钠龙。
  • WindowManager.LayoutParams.FLAG_FULLSCREEN 設(shè)置全屏;這個屬性也許是大家接觸的最多的一個屬性,很多應(yīng)用開發(fā)過程中會要求有些頁面需要動態(tài)設(shè)置Activity為全屏碴里,而我們只需要獲得Activity的WindowManager.LayoutParams并設(shè)置WindowManager.LayoutParams.FLAG_FULLSCREEN屬性就行沈矿。
  • WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON 設(shè)備常亮;設(shè)置這個屬性的窗口并闲,在窗口可見的情況下细睡,整個屏幕會處于常亮并且高亮度的狀態(tài),并且不受待機(jī)時間的約束帝火。
  • WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS 布局不受限制溜徙;設(shè)置這個屬性的窗口,將不再受設(shè)備顯示范圍邊界 的約束犀填,通俗點講蠢壹,就是窗口可以出設(shè)備之外,然后移除部分不可見九巡。具體會在坐標(biāo)參數(shù)中講到图贸。
  • WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 不設(shè)置聚焦;關(guān)于焦點獲得我有必要說明一下冕广,如果窗口獲得焦點的話疏日,只要窗口處于可視化狀態(tài),當(dāng)前設(shè)備的物理按鍵點擊事件都會被這個窗口接收撒汉,但是如果不設(shè)置窗口的焦點的話沟优,直接傳遞到之后窗口進(jìn)行接收。這就導(dǎo)致一個問題睬辐,如果你的需求要求你寫的懸浮窗點擊返回鍵能夠關(guān)閉或是進(jìn)行其他操作的話挠阁,你就必須讓你的窗口獲得焦點,并為當(dāng)前View設(shè)置按鍵監(jiān)聽事件溯饵。
  • WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE 取消觸摸事件侵俗; 設(shè)置這個屬性的窗口將不再處理任何Touch事件,就算顯示的View設(shè)置了onTouch事件丰刊,那么這個窗口就會是一個僵尸窗口隘谣。
  • WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL 不知道怎么去歸納,這個屬性還是比較有意思的啄巧,設(shè)置這個屬性的窗口寻歧,在窗口可見的情況下,就算窗口沒有設(shè)置屬性FLAG_NOT_FOCUSABLE棵帽,也就是在窗口獲得焦點的情況下,當(dāng)觸摸事件是在窗口之外區(qū)域的時候渣玲,窗口不在攔截觸摸事件逗概,而是將事件往下傳遞,也算是解決聚焦后的事件攔截問題吧忘衍。
  • WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER 顯示壁紙逾苫;官方文檔說明是在窗口之后顯示系統(tǒng)壁紙卿城,但是我親測,似乎并沒有這個想效果铅搓,還是這個屬性需要配合其他的屬性設(shè)置一起使用瑟押,希望有設(shè)置成功的小伙伴能夠在評論區(qū)分享你的結(jié)果。
  • WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED 鎖屏顯示星掰;關(guān)于這個屬性官方文檔給出的說明是在鎖屏的時候顯示的窗口多望,但是,實在慚愧镇饺,在下還是沒有能夠有一個實驗結(jié)果帖鸦,不知道是需要給權(quán)限呢還是需要同時進(jìn)行其他設(shè)置鄙皇。同樣,還是很希望有知道的小伙伴能夠在評論區(qū)向大家分享椎工。
  • WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON 點亮屏幕;設(shè)置這個屬性的窗口蜀踏,當(dāng)窗口顯示的時候维蒙,如果設(shè)備處于待機(jī)狀態(tài),會點亮設(shè)備果覆。這個應(yīng)該在很多鎖屏窗口中用的比較多颅痊,比如收到消息點亮屏幕。
  • WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH 這個也不知道怎么去歸納随静,也是一個比較有意思的屬性八千,之前我們說到FLAG_NOT_TOUCH_MODAL,在窗口獲得焦點的情況下燎猛,當(dāng)觸摸事件是在窗口之外區(qū)域的時候恋捆,窗口不在攔截觸摸事件,而是將事件往下傳遞重绷,而如果再設(shè)置這個屬性沸停,窗口能在MotionEvent.ACTION_OUTSIDE中收獲窗口之外的點擊事件,遺憾的是不能進(jìn)行屏蔽昭卓,也就是說事件依然會向下傳遞愤钾。

以上的也是最常用到的幾個flag屬性了吧,其他還有很多候醒,也希望大家空閑之余能夠去研究研究能颁,歡迎再評論區(qū)補(bǔ)充。

type

type主要用于表示window的類型倒淫。我們可以通過WindowManager.LayoutParams的type變量對窗口類型直接進(jìn)行設(shè)置伙菊。常用的窗口類型也就以下兩種:

  • WindowManager.LayoutParams.TYPE_APPLICATION_PANEL 我在之前文章中介紹過的PopupWindow,我也翻閱過PopupWindow的源碼,PopupWindow用的就是TYPE_APPLICATION_PANEL這個屬性類型镜硕。這種類型的窗口在顯示寄生于宿主窗口运翼,并顯示與宿主窗口之上,因此這種類型的窗口會隨著宿主窗口的關(guān)閉而關(guān)閉,顯然不能滿足我們懸浮窗的要求兴枯。
  • WindowManager.LayoutParams.TYPE_SYSTEM_ALERT 系統(tǒng)提示窗口,常見的比如內(nèi)存不夠的警告血淌、低電量警告。它總是出現(xiàn)在應(yīng)用程序窗口之上财剖,而這一點悠夯,正合我們做一個能夠顯示在任何應(yīng)用之上的懸浮迷你音樂盒的要求。
screenBrightness峰伙、buttonBrightness

其中screenBrightness表示屏幕的亮度疗疟,而buttonBrightness表示一般按鍵和鍵盤按鍵的亮度。它們都擁有以下三個系統(tǒng)屬性:

  • WindowManager.LayoutParams.BRIGHTNESS_OVERRIDE_OFF 最低屏幕亮度瞳氓。
  • WindowManager.LayoutParams.BRIGHTNESS_OVERRIDE_NONE 默認(rèn)屏幕亮度策彤。
  • WindowManager.LayoutParams.BRIGHTNESS_OVERRIDE_FULL 最高屏幕亮度。
dimAmount

講flag屬性的時候有提到過匣摘,這個參數(shù)是要和WindowManager.LayoutParams.FLAG_DIM_BEHIND這個flag屬性一起使用店诗,dimAmount的取值在0.0f~1.0f之間,取值越大背景的變暗程度越高音榜,默認(rèn)取值1.0f庞瘸。

width、height

這里的width赠叼、height其實和View中的width擦囊、height一樣的理解,就是控制窗口視圖的大小嘴办,可以具體取值瞬场,也可以使用系統(tǒng)屬性:

  • WindowManager.LayoutParams.WRAP_CONTENT 自適應(yīng)大小
  • WindowManager.LayoutParams.MATCH_PARENT 填滿整個布局
gravity

窗口的對齊方式,一般在創(chuàng)建窗口的時候涧郊,都會設(shè)置gravity為左上角對齊贯被,也就是Gravity.LEFT | Gravity.TOP,因為窗口的坐標(biāo)設(shè)置妆艘,是基于gravity來進(jìn)行計算的彤灶,設(shè)置gravity左上角,剛好是和系統(tǒng)的坐標(biāo)相對應(yīng)批旺,方便計算幌陕。

x、y

x和y用于控制窗口的坐標(biāo)位置汽煮,如果有設(shè)置gravity的話搏熄,x和y設(shè)置的就是在gravity這個基礎(chǔ)上的一個偏移量茅诱。不設(shè)置gravity的話,x和y就是一個絕對坐標(biāo)搬卒。因此,將gravity設(shè)置為Gravity.LEFT | Gravity.TOP是最易于開發(fā)的翎卓。需要注意的一點是:設(shè)置y的時候常常需要考慮狀態(tài)欄的高度契邀。
正常情況下,就算x和y的坐標(biāo)已經(jīng)在設(shè)備之外失暴,也會貼邊顯示坯门。而如果設(shè)置屬性FLAG_LAYOUT_NO_LIMITS則相對于系統(tǒng)的坐標(biāo)如果x和y超出設(shè)備,那么超出部分將無法顯示逗扒。

windowAnimations

windowAnimations控制的是窗口出現(xiàn)和消失的動畫效果古戴,設(shè)置的是要系統(tǒng)自帶的動畫效果(android.R.style之下的動畫效果),因為窗口管理器是不能訪問應(yīng)用資源的矩肩。

format

format可以理解為最后窗口生成的位圖是什么格式现恼,默認(rèn)背景是黑色的。一般我們都設(shè)置為PixelFormat.RGBA_8888黍檩,這樣我們的窗口就會有一個透明的背景叉袍。

alpha

這個不難理解,設(shè)置窗口的透明度刽酱。

其實WindowManager.LayoutParams的屬性有很多喳逛,全介紹一遍恐怕要講到天亮,而且還有一些我本人也沒有試過棵里,要是還有什么比較實用或是比較有趣的屬性润文,也歡迎小伙伴們在評論區(qū)留言!殿怜! 不勝感激5潋颉!N壤Α赠法!

下篇預(yù)告:像360懸浮窗那樣,用WindowManager實現(xiàn)炫酷的懸浮迷你音樂盒(下)乔夯,會有意想不到的驚喜砖织。

如果文中有表述不當(dāng)或闡述錯誤的地方,還望正在看文章的您可以幫忙指出末荐,有疑惑也可以在評論區(qū)提問或者私信侧纯,期待您的意見和建議,歡迎關(guān)注交流甲脏。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末眶熬,一起剝皮案震驚了整個濱河市妹笆,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌娜氏,老刑警劉巖拳缠,帶你破解...
    沈念sama閱讀 206,602評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異贸弥,居然都是意外死亡窟坐,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,442評論 2 382
  • 文/潘曉璐 我一進(jìn)店門绵疲,熙熙樓的掌柜王于貴愁眉苦臉地迎上來哲鸳,“玉大人,你說我怎么就攤上這事盔憨♂悴ぃ” “怎么了?”我有些...
    開封第一講書人閱讀 152,878評論 0 344
  • 文/不壞的土叔 我叫張陵郁岩,是天一觀的道長婿奔。 經(jīng)常有香客問我,道長问慎,這世上最難降的妖魔是什么脸秽? 我笑而不...
    開封第一講書人閱讀 55,306評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮蝴乔,結(jié)果婚禮上记餐,老公的妹妹穿的比我還像新娘。我一直安慰自己薇正,他們只是感情好片酝,可當(dāng)我...
    茶點故事閱讀 64,330評論 5 373
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著挖腰,像睡著了一般雕沿。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上猴仑,一...
    開封第一講書人閱讀 49,071評論 1 285
  • 那天审轮,我揣著相機(jī)與錄音,去河邊找鬼辽俗。 笑死疾渣,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的崖飘。 我是一名探鬼主播榴捡,決...
    沈念sama閱讀 38,382評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼朱浴!你這毒婦竟也來了吊圾?” 一聲冷哼從身側(cè)響起达椰,我...
    開封第一講書人閱讀 37,006評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎项乒,沒想到半個月后啰劲,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,512評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡檀何,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,965評論 2 325
  • 正文 我和宋清朗相戀三年呈枉,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片埃碱。...
    茶點故事閱讀 38,094評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖酥泞,靈堂內(nèi)的尸體忽然破棺而出砚殿,到底是詐尸還是另有隱情,我是刑警寧澤芝囤,帶...
    沈念sama閱讀 33,732評論 4 323
  • 正文 年R本政府宣布似炎,位于F島的核電站,受9級特大地震影響悯姊,放射性物質(zhì)發(fā)生泄漏羡藐。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,283評論 3 307
  • 文/蒙蒙 一悯许、第九天 我趴在偏房一處隱蔽的房頂上張望仆嗦。 院中可真熱鬧,春花似錦先壕、人聲如沸瘩扼。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,286評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽集绰。三九已至,卻和暖如春谆棺,著一層夾襖步出監(jiān)牢的瞬間栽燕,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,512評論 1 262
  • 我被黑心中介騙來泰國打工改淑, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留碍岔,地道東北人。 一個月前我還...
    沈念sama閱讀 45,536評論 2 354
  • 正文 我出身青樓朵夏,卻偏偏與公主長得像付秕,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子侍郭,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,828評論 2 345

推薦閱讀更多精彩內(nèi)容