源碼分析Dialog自定義大小無效坑

最近在項(xiàng)目中用到了自定義Dialog颅眶,以前也是經(jīng)常用寥院,只不過要么是用自帶的dialog樣式掰盘,要么也是很簡單的布局欠橘,所以并沒有重視修改dialog大小的坑矩肩。直到這次項(xiàng)目中產(chǎn)(keng)品(die)經(jīng)(wan)理(yi)死了都說dialog大小別扭要求改,然后突然發(fā)現(xiàn)自己自定義的dialog的大小不能調(diào)整后整個(gè)人都驚呆了肃续,因此打算深入源碼看看解決這個(gè)問題黍檩。本文分析的源代碼均來自Android API 24。


demo的自定義布局如下:

首先想著通過修改dialog的Window來進(jìn)行修改痹升,代碼如下:


開開心心運(yùn)行一下:

em.....emmmm???尼瑪建炫?這啥玩意兒?疼蛾?還是沒變?再怎么4000的大小也不會(huì)是這么個(gè)小玩意兒把艺配?郁悶之極....(我太仁慈大小給4000太小了察郁?)

又繼續(xù)試驗(yàn)衍慎,不斷的調(diào)整各種大小彼城,還是沒效果滓彰!最后求助網(wǎng)絡(luò)后發(fā)現(xiàn),設(shè)置窗口大小的代碼必須放在.show()之后才能有效果,代碼修改如下:
運(yùn)行后查看效果:
成功設(shè)置了大泻摺麦轰!開心得不得了G呛弧!款侵!

然而百思不得其解為什么必須要在show之后才能顯示末荐??按照正常邏輯不應(yīng)該在show之前設(shè)置大行滦狻甲脏??妹笆?

在網(wǎng)上找半天也沒找到前人們分析源碼块请,所以決定自己硬著頭皮看看源碼,點(diǎn)進(jìn)show()方法后進(jìn)行拳缠,一看大有文章墩新,先上代碼:

show方法中的代碼居然不是我想象中的一兩行代碼,而是那么多窟坐!首先在上圖中標(biāo)注1處,因?yàn)槲覀兪莿?chuàng)建新的dialog,所以會(huì)執(zhí)行dispatchOnCreate(null)這個(gè)方法海渊。顧名思義,調(diào)用創(chuàng)建狸涌,這里面肯定大有文章切省,猜測是進(jìn)行了Dialog的創(chuàng)建,我們跟進(jìn)去查看具體源碼帕胆。

跟進(jìn)去后發(fā)現(xiàn)里面調(diào)用了onCreate()方法朝捆,在這里是不是有種似曾相識的感覺?怎么感覺和Activity差不多了呢懒豹?按捺住基動(dòng)的內(nèi)心我們跟進(jìn)去繼續(xù)看看芙盘。因?yàn)镈ialog的onCreate()方法實(shí)現(xiàn)為空的,所以我們選擇一個(gè)子類來進(jìn)行查看脸秽,我們進(jìn)入AlertDialog中查看:



我們發(fā)現(xiàn)調(diào)用了mAlet.installContent()方法儒老,我們來看看這是什么東東。AlertController是一個(gè)AlertDialog的控制類记餐,包括在創(chuàng)建AlertDialog時(shí)(代碼如下):
AlertDialog mTextDialog = new AlertDialog.Builder(context).setTitle("溫馨提示").setView(view) .create();

在這里使用的Builder模式中驮樊,setTitle之類的設(shè)置參數(shù)也是先將參數(shù)設(shè)置給AlertController.Param。具體在這里就暫時(shí)不管。
我們繼續(xù)查看installContent()方法:


先設(shè)置dialog的contentView,然后調(diào)用setContentView()方法囚衔。是不是越來越熟悉這個(gè)套路挖腰!繼續(xù)忍著壓抑砰砰直跳的小內(nèi)心,繼續(xù)跟進(jìn)去看看练湿。

我們看到猴仑,在Dialog類中我們發(fā)現(xiàn)它最終調(diào)用了Window的setContentView()方法;而Window在Android中只有PhoneWindow這一個(gè)實(shí)現(xiàn)類。 接下來的工作就是和Activity中的步驟一模一樣肥哎,因?yàn)槎际钦{(diào)用Window的setContentView()方法辽俗;具體分析可看我記錄的另一篇文章內(nèi)容(傳送門:http://www.reibang.com/p/28bbb6778593)。
通過setContentView()方法后篡诽,創(chuàng)建了Dialog的decorView,并且將我們的自定義布局加入到decorView中崖飘。其中在這個(gè)過程中,mWindowAttributes的高度和寬度在mWindow.setContentView()中的installDecor()中的generateLayout()中被修改霞捡,在這里貼出修改部分的代碼:
修改窗口寬高調(diào)用代碼

setLayout()具體代碼

在上面圖中的標(biāo)注處調(diào)用了setLayout(int width,int height)方法坐漏,這里傳入了自適應(yīng)的常量方式。而在setLayout方法中首先獲取window的LayoutParams,然后修改了寬高碧信。因此在這里過后赊琳,Window的mWindowAttributes將會(huì)重新改變,因此導(dǎo)致了我們在show之前修改的mWindowAttributes值將被覆蓋砰碴,因此失效躏筏!
接下來把debug模式下錯(cuò)誤代碼的參數(shù)貼出來看看:

如下圖為debug下show之前設(shè)置WindowManager.LayoutParams的值,可以看到我們把window的寬高設(shè)置為1143.
下圖為show方法內(nèi)執(zhí)行過了dispatchOnCreate()方法后的WindowManager.LayoutParams的值.

可以看出就算之前設(shè)置參數(shù)呈枉,隨后在show方法中也會(huì)被覆蓋趁尼,因此在show之前設(shè)置參數(shù)無效。

所以我們因此只需要在show()之后設(shè)置即可猖辫。這樣就可以設(shè)置Dialog布局大小酥泞。而調(diào)用dialog.getWindow().setAttributes(params);這句話中,會(huì)觸發(fā)Window參數(shù)變化的接口啃憎,從而使得dialog重新設(shè)置自身大小芝囤。代碼如下:

至此我們就將設(shè)置Dialog的Window寬高沒有效果的原因分析完畢。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末辛萍,一起剝皮案震驚了整個(gè)濱河市悯姊,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌贩毕,老刑警劉巖悯许,帶你破解...
    沈念sama閱讀 216,324評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異辉阶,居然都是意外死亡先壕,警方通過查閱死者的電腦和手機(jī)瘩扼,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,356評論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來启上,“玉大人邢隧,你說我怎么就攤上這事店印「栽冢” “怎么了?”我有些...
    開封第一講書人閱讀 162,328評論 0 353
  • 文/不壞的土叔 我叫張陵按摘,是天一觀的道長包券。 經(jīng)常有香客問我,道長炫贤,這世上最難降的妖魔是什么溅固? 我笑而不...
    開封第一講書人閱讀 58,147評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮兰珍,結(jié)果婚禮上侍郭,老公的妹妹穿的比我還像新娘。我一直安慰自己掠河,他們只是感情好亮元,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,160評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著唠摹,像睡著了一般爆捞。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上勾拉,一...
    開封第一講書人閱讀 51,115評論 1 296
  • 那天煮甥,我揣著相機(jī)與錄音,去河邊找鬼藕赞。 笑死成肘,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的斧蜕。 我是一名探鬼主播双霍,決...
    沈念sama閱讀 40,025評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼惩激!你這毒婦竟也來了店煞?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,867評論 0 274
  • 序言:老撾萬榮一對情侶失蹤风钻,失蹤者是張志新(化名)和其女友劉穎顷蟀,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體骡技,經(jīng)...
    沈念sama閱讀 45,307評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡鸣个,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,528評論 2 332
  • 正文 我和宋清朗相戀三年羞反,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片囤萤。...
    茶點(diǎn)故事閱讀 39,688評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡昼窗,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出涛舍,到底是詐尸還是另有隱情澄惊,我是刑警寧澤,帶...
    沈念sama閱讀 35,409評論 5 343
  • 正文 年R本政府宣布富雅,位于F島的核電站掸驱,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏没佑。R本人自食惡果不足惜毕贼,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,001評論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望蛤奢。 院中可真熱鬧鬼癣,春花似錦、人聲如沸啤贩。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,657評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽瓜晤。三九已至锥余,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間痢掠,已是汗流浹背驱犹。 一陣腳步聲響...
    開封第一講書人閱讀 32,811評論 1 268
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留足画,地道東北人雄驹。 一個(gè)月前我還...
    沈念sama閱讀 47,685評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像淹辞,于是被迫代替她去往敵國和親医舆。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,573評論 2 353

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