Android 如何計算View的Size

2021-08-15 05:43:02 字數 4172 閱讀 7270

** 注:本文參考鏈結how android caculates view size

本文例子如下所示:

計算view大小的過程可以分為以下幾個步驟:

確定view想要的size(layoutparams)

確定parent view的情況(measurespec)

在parent view的限制下,根據view的layoutparams,確定view的大小

layoutparams用於view表示想要的size的模式。有以下三種:

fill_parent / match_parent (-1)

view的size和parent view的size一樣大

wrap_content(-2)

view的size僅包裹其內容即可

指定的值(>0)

view的size為指定的size大小

measurespec表示當前view的「約束」(在onmeasure中傳入)。約束含模式mode和數值size,當前view根據mode來決定如何看待其中的size。mode有三種,如下所示:

unspecified

對當前view的size沒有約束

exactly

當前view的bounds(可以理解成「可以使用的範圍」)為確定的size,也可以理解成parent view希望當前view(有強制的意味)使用給定的size

at_most

當前view的大小不可超過指定的size

可以利用measurespec的getmode取出具體值.size為8個byte的int值,mode放在前2個bit中。這裡可以利用measurespec的getsize取出size的具體值。

view通過onmeasure確定自己的大小。確定自己的大小時,需要的東西有:

約束measurespec

自己的layoutparams

如果有child view,那麼需要獲取child view的大小

最終確定當前view的size分別為:

measurewidth

measureheight

以前面例子中的textview為例,其onmeasure中傳入的measurespec為:

width

mode:at_most size:parentcontentwidth(linearlayout的寬-padding)

height

mode:unspecified size:不確定

注:這裡先不解釋為什麼measurespec是這樣的。

textview的layoutparams為:

width

match_parent

height

wrap_content

然後textview根據約束和layoutparams確定自己的大小,包括但不限於以下過程:

設定寬度為parentcontentwidth,考慮margin確定字元可用範圍

根據字元高度和字型設定(根據是否超過parentcontentwidth確定是否換行)等計算字元所佔的高度(沒有限制)。

設定measurewidth和measureheight

以前面例子中的linearlayout為例,假設該linearlayout為activity中的root layout其onmeasure中傳入的measurespec為:

width

mode:exactly size:parentcontentwidth(linearlayout的parent view的寬-padding)

height

mode:at_most size:parentcontentheight(linearlayout的parent view的高-padding)

relativelayout的layoutparams為:

width

match_parent

height

wrap_content

orientation

vertical

然後linearlayout根據約束和layoutparams確定自己的大小,包括但不限於以下過程:

確定child view的排列方式

確定textview的size

確定imageview的size

根據自身的設定,設定measurewidth和measureheight

要確定child view的size,就要呼叫child view的onmeasure,傳入合適的measurespec,表明parent view對child的約束。

根據parent view的不同module和child view的不同layoutparams,有如下規則:

當parent view的mode是exactly時:

child layout

mode

size

exact size

exactly

childsize

child wants a specific size.

match_parent

exactly

parentcontentsize

child wants to be parent's size.

wrap_content

at_most

parentcontentsize

child wants to determine its own size. it can not be bigger than parent.

當parent view的mode是at_most時:

child layout

mode

size

exact size

exactly

childsize

child wants a specific size

match_parent

at_most

parentcontentsize

child wants to be parent's size, but parent's size is not fixed. constrain child to not be bigger than parent.

wrap_content

at_most

parentcontentsize

child wants to determine its own size, but it can not be bigger than parent.

當parent view的mode是unspecified時:

child layout

mode

size

exact size

exactly

childsize

child wants a specific size.

match_parent

unspecified

can not decide yet

child wants to be parent's size. child will decide its own size later.

wrap_content

unspecified

can not decide yet

child wants to be its own size. child will decide its own size later.

以例子中的textview為例:

linearlayout的width mode為exactly,textview的width layout param為match_parent

linearlayout的height mode為at_most,textview的height layout param為wrap_content

所以textview的onmeasure會被傳入:

width

mode:exactly size:parentcontentwidth(linearlayout的寬-padding)

height

mode:at_most size:parentcontentheight(linearlayout的高-padding)

textview可以根據上述約束計算自己的大小。imageview同理。最後linearlayout根據imageview和textview的大小計算自己的大小。注意這裡沒有weight的設定,所以onmeasure只執行一次。

Android 如何計算View的Size

注 本文參考鏈結how android caculates view size 本文例子如下所示 計算view大小的過程可以分為以下幾個步驟 確定view想要的size layoutparams 確定parent view的情況 measurespec 在parent view的限制下,根據view...

Android如何計算View的深度

今天在qq群上,看到大家談到了乙個面試題,就是如何求view樹的深度。在我們專案中基本上比較少需要到這個計算,所以可能一下子會蒙圈了。我們知道,android的檢視是一顆樹的形式,那麼即使關於android的view樹方面很多計算,便可以利用樹的原理來計算。談到樹,我們在書本上最常看到的就是二叉樹,...

開發者指南 Android如何繪製View

android畫的操作是由framework層來進行處理的,整個 draw是從根view開始的,viewgroup向子view發出 draw的請求,然後子view負責自己重畫它們的invalid區域。drawing乙個layout必須通過兩個步驟 1.測量。measure 從根節點到葉子節點依次測量...