在 Compose 中,您可以將多個修飾符鏈結在一起,變更可組合項目的外觀和風格。這些修飾符鏈可能會影響傳遞至可組合項的限制,這些限制會定義寬度和高度界限。
本頁說明鏈結修飾符如何影響限制,進而影響可組合項的測量和放置位置。
UI 樹狀結構中的修飾符
如要瞭解修飾符如何相互影響,建議您將修飾符在 UI 樹狀結構中的顯示方式視覺化,這是在組合階段產生。詳情請參閱「組合」一節。
在 UI 樹狀結構中,您可以將修飾符視為版面配置節點的包裝函式節點:

為可組合函式新增多個修飾符時,會建立修飾符鏈結。當您鏈結多個修飾符時,每個修飾符節點都會包裝鏈結的其餘部分和其中的版面配置節點。舉例來說,當您鏈結 clip
和 size
修飾符時,clip
修飾符節點會包裝 size
修飾符節點,然後包裝 Image
版面配置節點。
在版面配置階段,樹狀結構的演算法保持不變,但也會一併造訪每個修飾符節點。這樣一來,修飾符就能變更所包裝修飾符或版面配置節點的大小需求和位置。
如圖 2 所示,Image
和 Text
可組合項的實作本身是由一連串的修飾符組成,這些修飾符會包裝單一版面配置節點。Row
和 Column
的實作只是版面配置節點,用於說明如何配置子項。

總結來說:
- 修飾符會包裝單一修飾符或版面配置節點。
- 版面配置節點可以配置多個子項節點。
以下章節說明如何使用這個心智模型來推斷修飾符鏈結,以及鏈結會如何影響可組合項的大小。
版面配置階段的限制
版面配置階段會依循三步驟演算法,找出每個版面配置節點的寬度、高度和 x、y 座標:
- 測量子項:節點會測量子項 (如有)。
- 決定自身大小:節點會根據這些測量結果決定自身大小。
- 放置子項:每個子項節點都會放置在相對於節點本身的位置。
Constraints
在演算法的前兩個步驟中,協助找出節點的合適大小。限制會定義節點寬度和高度的最小及最大界限。節點決定大小時,測量大小應落在這個大小範圍內。
限制類型
限制可以是下列其中一項:
- 有界:節點有寬度和高度的上下限。

- 無界限:節點不受任何大小限制。寬度和高度上限設為無限大。

- 確切:節點必須遵循確切的大小規定。最小值和最大值範圍設為相同的值。

- 組合:節點遵循上述限制類型的組合。 舉例來說,限制可以限制寬度,同時允許無上限的最大高度,或是設定確切寬度,但提供有上限的高度。

下一節將說明如何從父項將這些限制傳遞至子項。
限制條件如何從父項傳遞至子項
在「版面配置階段的限制」一節所述演算法的第一個步驟中,限制會從父項傳遞至 UI 樹狀結構中的子項。
當父項節點測量子項時,會將這些限制提供給每個子項,讓子項瞭解允許的大小。接著,當該元素決定自身大小時,也會遵守父項傳入的限制。
演算法的運作方式大致如下:
- 為決定實際要占用的尺寸,UI 樹狀結構中的根節點會測量其子項,並將相同限制轉送至第一個子項。
- 如果子項是不會影響測量的修飾符,則會將限制轉送至下一個修飾符。除非到達會影響測量的修飾符,否則限制會原封不動地傳遞到修飾符鏈。然後系統會相應地調整限制大小。
- 到達沒有任何子項的節點 (稱為「葉節點」) 後,該節點會根據傳入的限制條件決定大小,並將解析後的大小傳回給父項。
- 父項會根據這個子項的測量結果調整限制,並使用這些調整後的限制呼叫下一個子項。
- 測量完父項的所有子項後,父項節點會決定自身的大小,並將該大小傳達給自己的父項。
- 這樣一來,整個樹狀結構就會以深度優先方式遍歷。最後,所有節點都會決定自身的大小,測量步驟也隨之完成。
如需深入範例,請觀看「限制和修飾符順序」影片。
影響限制的修飾符
您在上一個部分中瞭解到,部分修飾符可能會影響限制大小。以下各節說明會影響限制的特定修飾符。
size
修飾符
size
修飾符會宣告內容的偏好大小。
舉例來說,下列 UI 樹狀結構應在 300dp
的容器中以 200dp
方式算繪。這些限制是有界限的,允許的寬度介於 100dp
和 300dp
之間,高度介於 100dp
和 200dp
之間:

size
修飾符會調整傳入的限制,使其符合傳遞給修飾符的值。
在本範例中,值為 150dp
:

size
修飾符,將限制條件調整為 150dp
。如果寬度和高度小於最小限制邊界,或大於最大限制邊界,修飾符會盡可能符合傳遞的限制,同時遵守傳遞的限制:

size
修飾符會盡可能遵守傳遞的限制。請注意,串連多個 size
修飾符無效。第一個 size
修飾符會將最小值和最大值限制都設為固定值。即使第二個大小修飾符要求較小或較大的大小,仍須遵守傳入的確切界限,因此不會覆寫這些值:

size
修飾符的鏈結,其中傳入的第二個值 (50dp
) 不會覆寫第一個值 (100dp
)。requiredSize
修飾符
如要讓節點覆寫輸入限制,請使用 requiredSize
修飾符,而非 size
。requiredSize
修飾符會取代傳入的限制條件,並將您指定的大小做為確切的界線傳遞。
當大小傳回樹狀結構時,子節點會置中於可用空間:

requiredSize
修飾符會覆寫 size
修飾符的輸入限制。width
和 height
修飾符
size
修飾符會調整限制條件的寬度和高度。使用 width
修飾符時,您可以設定固定寬度,但高度則不確定。同樣地,您可以使用 height
修飾符設定固定高度,但寬度則不設限:

width
修飾符和 height
修飾符分別設定固定寬度和高度。sizeIn
修飾符
sizeIn
修飾符可讓您設定寬度和高度的確切最小值和最大值限制。如要精細控制限制,請使用 sizeIn
修飾符。

sizeIn
修飾符,並搭配 minWidth
、maxWidth
、minHeight
和 maxHeight
集合。範例
本節會顯示並說明幾個程式碼片段的輸出內容,這些程式碼片段含有鏈結修飾符。
Image( painterResource(R.drawable.hero), contentDescription = null, Modifier .fillMaxSize() .size(50.dp) )
這個程式碼片段會產生下列輸出內容:
fillMaxSize
修飾符會變更限制,將寬度和高度下限都設為最大值,也就是寬度300dp
和高度200dp
。- 即使
size
修飾符想使用50dp
大小,仍須遵守輸入的最小限制。因此,size
修飾符也會透過200
輸出300
的確切限制範圍,有效忽略size
修飾符中提供的值。 Image
會遵循這些界線,並回報300
x200
的大小,這會一路傳遞到樹狀結構。
Image( painterResource(R.drawable.hero), contentDescription = null, Modifier .fillMaxSize() .wrapContentSize() .size(50.dp) )
這個程式碼片段會產生下列輸出內容:
fillMaxSize
修飾符會調整限制,將寬度和高度下限都設為最大值,也就是寬度為300dp
,高度為200dp
。wrapContentSize
修飾符會重設最小限制。因此,雖然fillMaxSize
會產生固定限制,但wrapContentSize
會將其重設為有界限制。現在,下列節點可以再次佔用整個空間,或小於整個空間。size
修飾符會將限制設為50
的下限和上限。Image
會解析為50
x50
的大小,而size
修飾符會轉送該大小。wrapContentSize
修飾符具有特殊屬性。這個修飾符會取得子項,並將其放在傳遞給它的可用最小界限中央。因此,它傳達給父項的大小等於傳遞給它的最小界限。
只要結合三種修飾符,即可定義可組合項目的尺寸,並將其置中於父項中。
Image( painterResource(R.drawable.hero), contentDescription = null, Modifier .clip(CircleShape) .padding(10.dp) .size(100.dp) )
這個程式碼片段會產生下列輸出內容:
clip
修飾符不會變更限制。padding
修飾符會降低限制上限。size
修飾符會將所有限制設為100dp
。Image
會遵守這些限制,並回報100
x100dp
的大小。padding
修飾符會在所有大小上新增10dp
,因此回報的寬度和高度會增加20dp
。- 現在在繪圖階段,
clip
修飾符會對120
的畫布執行120dp
。因此,系統會建立該大小的圓形遮罩。 - 接著,
padding
修飾符會在所有大小上將內容內插10dp
,因此畫布大小會降低至100
(降低100dp
)。 Image
會繪製在該畫布中。系統會根據120dp
的原始圓圈裁剪圖片,因此輸出結果並非圓形。