在 Compose 中,您可以將多個修飾符鏈結在一起,以變更可組合項的外觀與風格。這些修飾符鏈會影響傳送至可組合項的限制條件,也就是定義寬度和高度邊界。
本頁面說明鏈結修飾符如何影響限制,進而影響可組合項的測量結果和位置。
UI 樹狀結構中的修飾符
如要瞭解修飾符如何互相影響,建議您將這些修飾符在 UI 樹狀結構中 (在組合階段產生的) 中呈現的方式呈現。詳情請參閱「組合」一節。
在 UI 樹狀結構中,您可以將修飾符視覺化為版面配置節點的包裝函式節點:
只要在可組合項中加入多個修飾符,就會建立一連串修飾符。鏈結多個修飾符時,每個修飾符節點都會納入鏈結的其餘部分以及其中的版面配置節點。舉例來說,當您鏈結 clip
和 size
修飾符時,clip
修飾符節點會包裝 size
修飾詞節點,然後納入 Image
版面配置節點。
在版面配置階段,行走樹狀結構的演算法會保持不變,但會瀏覽每個修飾符節點。如此一來,修飾符就能變更其所包裝的修飾符或版面配置節點的大小要求和位置。
如圖 2 所示,Image
和 Text
可組合項本身的實作方式是由包裝單一版面配置節點的修飾符鏈結組成。Row
和 Column
的實作只是版面配置節點,用來描述如何安排子項的版面配置。
總結:
- 修飾符會納入單一修飾符或版面配置節點。
- 版面配置節點可以配置多個子節點。
以下各節說明如何使用這個心理模型來解釋修飾詞鏈結,以及該模型如何影響可組合項的大小。
版面配置階段的限制
版面配置階段會按照三步驟演算法尋找每個版面配置節點的寬度、高度和 x Y 座標:
- 測量子項:節點測量其子項 (如有)。
- 決定自己的大小:節點會根據這些測量值決定節點大小。
- 放置子項:每個子節點都會根據節點自己的位置放置。
在演算法的前兩個步驟中,Constraints
會協助找出節點適用的大小。限制會定義節點寬度與高度的上下限。當節點決定其大小時,其測量大小應落在這個大小範圍內。
限制的類型
限制可以是下列其中一種:
- Bounded:節點有寬度和下限上限。
- 未界限:節點不受任何大小的限制。寬度和高度上限會設為無限大。
- 完全比對:系統要求節點符合確切的大小規定。下限和上限會設定為相同的值。
- 組合:節點會遵循上述限制類型的組合。舉例來說,限制可以把寬度限定在不設限的高度上限,也可以設定確切寬度但提供有限的高度。
下一節將說明這些限制如何從父項傳遞至子項。
限制從父項傳遞至子項的方式
在版面配置階段中的限制所述演算法的第一個步驟中,限制會從父項向下傳遞至 UI 樹狀結構中的子項。
父項節點測量子項時,會為每個子項提供這些限制,讓他們瞭解可設定的大小。之後,當它決定自己的大小時,也會遵循其本身父項所傳入的限制。
大致來說,演算法的運作方式如下:
- 在決定實際要佔用的大小時,UI 樹狀結構中的根節點會測量其子項,並將相同的限制轉送至其第一個子項。
- 如果子項是不會影響測量的修飾符,則會將限制轉送至下一個修飾符。除非觸及會影響測量的修飾符,否則這些限制會依原樣向下傳遞給修飾符鏈。然後,這些限制會隨之重新調整。
- 到達沒有任何子項 (稱為「分葉節點」的節點) 後,就會根據傳入的限制決定其大小,並將這個已解析的大小傳回其父項。
- 父項會根據此子項的測量值調整其限制,並以這些經過調整的限制來呼叫下一個子項。
- 測量父項的所有子項後,父項節點會決定其自己的大小,並將這個大小傳達給其父項。
- 如此一來,整個樹狀結構都會先進行深度掃遍。最後,所有節點都決定了大小,評估步驟也已完成。
如需詳細範例,請參閱「限制和修飾符順序」影片。
影響限制的修飾符
您在先前的章節中學到,有些修飾符會影響限制大小。以下各節說明會影響限制的特定修飾符。
size
個修飾符
size
修飾符會宣告內容的偏好大小。
舉例來說,下列 UI 樹狀結構應由 200dp
在 300dp
的容器中轉譯。限制條件設有界限,允許介於 100dp
和 300dp
之間的寬度,高度介於 100dp
和 200dp
之間:
size
修飾符會調整傳入的限制,使其符合傳遞的值。在這個範例中,值為 150dp
:
如果寬度和高度小於最小限制範圍,或大於最大限制邊界,修飾符會盡可能比對通過的限制,但仍遵循傳入的限制:
請注意,鏈結多個 size
修飾符無法運作。第一個 size
修飾符會將最小和最大限制設定為固定值。即使第二個大小修飾符要求較小或更大尺寸,仍需要符合傳入的確切邊界,因此不會覆寫這些值:
requiredSize
個修飾符
如果您需要節點覆寫傳入的限制,請使用 requiredSize
修飾符,而非 size
。requiredSize
修飾符會取代傳入的限制,並將您指定的大小做為確切邊界傳遞。
大小向上傳遞至樹狀結構後,子項節點會在可用空間的中央:
width
和 height
修飾符
size
修飾符會調整限制條件的寬度和高度。使用 width
修飾符,您可以設定固定寬度,但不要決定高度。同樣地,使用 height
修飾符時,您可以設定固定高度,但不要決定寬度:
sizeIn
個修飾符
sizeIn
修飾符可讓您針對寬度和高度設定確切的最小和最大限制。如果您需要精細控管限制,請使用 sizeIn
修飾符。
範例
本節會顯示並說明數個含有鏈結修飾符的程式碼片段輸出內容。
Image( painterResource(R.drawable.hero), contentDescription = null, Modifier .fillMaxSize() .size(50.dp) )
這個程式碼片段會產生以下輸出內容:
fillMaxSize
修飾符會變更限制條件,將最小寬度和高度設為最大值,寬度為300dp
,高度為200dp
。- 即使
size
修飾符想使用50dp
的大小,仍需要遵循傳入的最小限制。因此,size
修飾符也會輸出200
的300
確切限制邊界,有效忽略size
修飾符中提供的值。 Image
會遵循這些邊界,並依照200
回報300
的大小,並將其傳遞至樹狀結構中。
Image( painterResource(R.drawable.hero), contentDescription = null, Modifier .fillMaxSize() .wrapContentSize() .size(50.dp) )
這個程式碼片段會產生以下輸出內容:
fillMaxSize
修飾符會調整限制條件,將最小寬度和高度設為最大值 - 寬度為300dp
,高度設為200dp
。wrapContentSize
修飾符會重設最小限制。因此,雖然fillMaxSize
導致限制固定,但wrapContentSize
會將其重設為受限的限制條件。下列節點現在可以再次佔據整個空間,或小於整個空間。size
修飾符會將限制設為50
的上下限。Image
會由50
解析為50
的大小,size
修飾符則會轉向此大小。wrapContentSize
修飾符具有特殊屬性。系統會擷取其子項,並將其置於傳遞給它的可用最低邊界中心。因此,其傳達給父項的大小等於傳入的最小邊界。
只要結合三個修飾符,就能定義可組合項的大小,並將其置於其父項中心。
Image( painterResource(R.drawable.hero), contentDescription = null, Modifier .clip(CircleShape) .padding(10.dp) .size(100.dp) )
這個程式碼片段會產生以下輸出內容:
clip
修飾符不會變更限制條件。padding
修飾符會降低限制條件上限。size
修飾符會將所有限制條件設為100dp
。Image
遵循這些限制,並依照100dp
回報100
的大小。padding
修飾符會為所有大小加上10dp
,因此回報的寬度和高度會增加20dp
。- 在繪圖階段,
clip
修飾符會在120
的120dp
畫布上執行。因此,系統會建立該大小的圓形遮罩。 - 接著,
padding
修飾符會在所有大小的10dp
上將內容插邊,因此將畫布大小減少為100dp
的100
。 Image
會顯示在該畫布中。圖片是根據120dp
的原始圓形裁剪,因此輸出內容為非圓形結果。