自定義View

4.1 初始ViewRoot和DecorView
View的繪制流程是從ViewRoot的performTraversal的開(kāi)始的跟畅。經(jīng)過(guò)measure,layout,draw三個(gè)過(guò)程汇荐。
performTraversal會(huì)依次調(diào)用performMeasure,performLayout,performDraw來(lái)完成頂級(jí)View的measure,layout和draw過(guò)程。performMeasure方法中會(huì)調(diào)用measure方法龟虎,在measure方法中又會(huì)調(diào)用onMeasure方法锋勺,在onMeasure方法中會(huì)對(duì)所有的子元素進(jìn)行measure過(guò)程,這個(gè)時(shí)候measure流程就從父容器傳遞到子元素了芽狗,這樣就完成了一次measure過(guò)程绢掰,layout和draw的過(guò)程類(lèi)似。
(1)measure過(guò)程決定了View的寬高童擎,幾乎在所有情況下滴劲,這個(gè)寬高都等于View最終的寬高。getMeasuredHeight(),getMeasuredWidth()來(lái)得到測(cè)量寬高顾复。
(2)layout過(guò)程決定了View四個(gè)頂點(diǎn)的位置班挖,和View實(shí)際的寬高。通過(guò)getHeight()和getWidth()來(lái)得到實(shí)際的寬高芯砸。
(3)draw過(guò)程決定view的顯示萧芙。
DecorView是一個(gè)FrameLayout,包含了一個(gè)豎直方向的LinearLayout给梅,上面是標(biāo)題欄,下面是內(nèi)容双揪。
4.1 理解MeasureSpec
(1)MeasureSpec和LayoutParams的對(duì)應(yīng)關(guān)系动羽。
在View測(cè)量的時(shí)候,系統(tǒng)會(huì)將LayoutParams在父容器的約束下轉(zhuǎn)換成MeasureSpec渔期,在根據(jù)MeasureSpec來(lái)決定View測(cè)量后的寬高运吓。
MeasureSpec不是唯一由LayoutParams決定的,而是和父容器一起決定的擎场。對(duì)于DecorView羽德,它的MeasureSpec是由窗口的大小和自身的LayoutParams確定的。
(2)普通view的MeasureSpec的創(chuàng)建規(guī)則
當(dāng)View采用固定寬高時(shí)迅办,不管父容器采用什么MeasureSpec宅静,View的MeasureSpec都是精確模式,大小等于LayoutParams中的大小站欺。
當(dāng)View采用match_parent時(shí)姨夹,如果父容器是精確模式,那么view也是精確模式矾策,大小是父容器剩余的大小磷账。如果父容器是最大模式,那么view也是最大模式贾虽,大小不超過(guò)父容器的剩余空間逃糟。
當(dāng)View采用wrap_content時(shí),不管父容器是什么模式蓬豁,View都是最大模式绰咽,大小是不超過(guò)父容器剩余的大小。
4.3 View的工作流程
(1)measure過(guò)程
view的測(cè)量過(guò)程由measure方法(final)完成地粪,在measure方法中又會(huì)調(diào)用onMeasure方法取募,onMeasure會(huì)調(diào)用setMeasuredDimension方法,setMeasuredDimension會(huì)設(shè)置View寬高的測(cè)量值蟆技。當(dāng)View的SpecMode是AT_MOST和EXACTLY時(shí)玩敏,getDefaultSize返回的是measureSpec中的specSize的大小,而當(dāng)View的SpecMode是UNSPECIFIED的時(shí)候
返回的是size,是getSuggestedMinimumWidth的返回值质礼,如果View沒(méi)有設(shè)置背景旺聚,那么返回的是android:midWidth這個(gè)屬性,如果設(shè)置了背景眶蕉,返回的是android:minWidth和背景最小寬度中兩者的的最大值砰粹。

Paste_Image.png

(2)ViewGroup的measure過(guò)程
viewGroup除了要完成自己的measure以外,還會(huì)遍歷去調(diào)用所有子元素的measure方法妻坝,各個(gè)子元素在遞歸完成此過(guò)程伸眶。ViewGroup是一個(gè)抽象類(lèi),因此它沒(méi)有重寫(xiě)onMeasure方法刽宪。在onMeasure方法中拿到的測(cè)量寬高是不準(zhǔn)確的厘贼,在onLayout中獲得測(cè)量寬高或者最終的寬高。view的measure過(guò)程和Activity的生命周期方法不是同步執(zhí)行的圣拄,因此無(wú)法保證Activity執(zhí)行了onCreate嘴秸、onStart、onResume時(shí)某個(gè)view已經(jīng)測(cè)量完畢了庇谆。如果view還沒(méi)有測(cè)量完畢岳掐,那么獲得的寬高就都是0。下面是四種解決該問(wèn)題的方法:
一:onWindowFocusChanged():View已經(jīng)初始化完畢饭耳,寬高已經(jīng)準(zhǔn)備好了串述。
二:view.post(runnable):通過(guò)post可以將一個(gè)runnable投射到消息隊(duì)列的尾部,然后等待Looper調(diào)用此runnable的時(shí)候寞肖,View就已經(jīng)初始化好了纲酗。
三:ViewTreeObserver:使用ViewTreeObserver的眾多回調(diào)方法可以完成這個(gè)功能,比如使用onGlobalLayoutListener接口新蟆,當(dāng)view樹(shù)的狀態(tài)發(fā)生改變或者view樹(shù)內(nèi)部的view的可見(jiàn)性發(fā)生改變時(shí)觅赊,onGlobalLayout方法將被回調(diào)。伴隨著view樹(shù)的狀態(tài)改變琼稻,這個(gè)方法也會(huì)被多次調(diào)用吮螺。
在view的默認(rèn)實(shí)現(xiàn)中,view的測(cè)量寬高和最終寬高是相等的帕翻,只不過(guò)測(cè)量寬高形成于measure過(guò)程鸠补,而最終寬高形成于layout過(guò)程。
(3)layout過(guò)程
ViewGroup的位置被確定以后熊咽,它在onLayout中會(huì)遍歷所有的子元素并調(diào)用其layout方法莫鸭,在layout方法中OnLayout方法又會(huì)被調(diào)用。layout方法的流程:首先會(huì)通過(guò)setFrame方法來(lái)設(shè)定View的四個(gè)頂點(diǎn)横殴,View一旦確定被因,View在父容器中的位置也被確定了,接著會(huì)調(diào)用onLayout方法衫仑,這個(gè)方法的用途是確定子元素的位置梨与。onLayout的具體實(shí)現(xiàn)和具體的布局有關(guān)。
(4)draw過(guò)程
1.繪制背景:background.draw(canvas)文狱;
2.繪制自己:onDraw()粥鞋;
3.繪制children:dispatchDraw;
4.繪制裝飾:onDrawScrollBars瞄崇。
4.4 自定義view
(1)繼承view重寫(xiě)onDraw方法需要自己支持wrap_content呻粹,并且padding也要自己處理壕曼。繼承特定的View例如TextView不需要考慮。
繼承自ViewGroup要在onMeasure和onLayout中考慮padding和子元素的margin對(duì)其造成的影響等浊。
(2)盡量不要在View中使用Handler腮郊,因?yàn)関iew內(nèi)部本身已經(jīng)提供了post系列的方法,完全可以替代Handler的作用筹燕。
(3)view中如果有線程或者動(dòng)畫(huà)轧飞,需要在onDetachedFromWindow方法中及時(shí)停止。
(4)處理好view的滑動(dòng)沖突情況撒踪。
如何處理wrap_content,原因?
如果在View在布局中使用wrap_content,那么它的specMode是AT_MOST,在這種模式下过咬,它的寬高等于specSize,而specSize等于parentSize制妄。parentSize是父容器目前剩余空間的大小掸绞。和match_parent一致。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末耕捞,一起剝皮案震驚了整個(gè)濱河市集漾,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌砸脊,老刑警劉巖具篇,帶你破解...
    沈念sama閱讀 218,546評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異凌埂,居然都是意外死亡驱显,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,224評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)瞳抓,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)埃疫,“玉大人,你說(shuō)我怎么就攤上這事孩哑∷ㄋ” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,911評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵横蜒,是天一觀的道長(zhǎng)胳蛮。 經(jīng)常有香客問(wèn)我,道長(zhǎng)丛晌,這世上最難降的妖魔是什么仅炊? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,737評(píng)論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮澎蛛,結(jié)果婚禮上抚垄,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好呆馁,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,753評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布桐经。 她就那樣靜靜地躺著,像睡著了一般浙滤。 火紅的嫁衣襯著肌膚如雪次询。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,598評(píng)論 1 305
  • 那天瓷叫,我揣著相機(jī)與錄音,去河邊找鬼送巡。 笑死摹菠,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的骗爆。 我是一名探鬼主播次氨,決...
    沈念sama閱讀 40,338評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼摘投!你這毒婦竟也來(lái)了煮寡?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,249評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤犀呼,失蹤者是張志新(化名)和其女友劉穎幸撕,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體外臂,經(jīng)...
    沈念sama閱讀 45,696評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡坐儿,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,888評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了宋光。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片貌矿。...
    茶點(diǎn)故事閱讀 40,013評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖罪佳,靈堂內(nèi)的尸體忽然破棺而出逛漫,到底是詐尸還是另有隱情,我是刑警寧澤赘艳,帶...
    沈念sama閱讀 35,731評(píng)論 5 346
  • 正文 年R本政府宣布酌毡,位于F島的核電站,受9級(jí)特大地震影響蕾管,放射性物質(zhì)發(fā)生泄漏阔馋。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,348評(píng)論 3 330
  • 文/蒙蒙 一娇掏、第九天 我趴在偏房一處隱蔽的房頂上張望呕寝。 院中可真熱鬧,春花似錦、人聲如沸下梢。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,929評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)孽江。三九已至讶坯,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間岗屏,已是汗流浹背辆琅。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,048評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留这刷,地道東北人婉烟。 一個(gè)月前我還...
    沈念sama閱讀 48,203評(píng)論 3 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像暇屋,于是被迫代替她去往敵國(guó)和親似袁。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,960評(píng)論 2 355

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