在 Compose 中,您可以將多個修飾符鏈結在一起,變更可組合項的外觀和風格。這些修飾符鏈結可能會影響傳遞至可組合項的限制,這些限制會定義寬度和高度的邊界。
本頁說明鏈結修飾符如何影響限制條件,以及可組合項的測量和位置。
UI 樹狀結構中的修飾符
如要瞭解修飾符如何相互影響,建議您以視覺化方式呈現修飾符在組合階段所產生 UI 樹狀結構中的顯示方式。詳情請參閱「組合」一節。
在 UI 樹狀結構中,您可以將修飾符視覺化,做為版面配置節點的包裝函式節點:
在可組合函式中加入多個修飾符,會建立修飾符鏈結。鏈結多個修飾符時,每個修飾符節點都會納入鏈結的其餘部分和版面配置節點中。舉例來說,當您鏈結 clip
和 size
修飾符時,clip
修飾符節點會納入 size
修飾符節點,然後包裝 Image
版面配置節點。
在版面配置階段,引導樹狀結構的演算法維持不變,但也會造訪每個修飾符節點。如此一來,修飾符就能變更其包裝的修飾符或版面配置節點的大小需求和位置。
如圖 2 所示,Image
和 Text
可組合項的實作方式包含包裝單一版面配置節點的修飾符鏈結。Row
和 Column
的實作只是版面配置節點,用來描述如何安排子項的版面配置。
總結:
- 修飾符會納入單一修飾符或版面配置節點。
- 版面配置節點可以配置多個子節點。
以下各節將說明如何使用這個心理模型,推斷修飾符鏈結及其對可組合項大小的影響。
版面配置階段的限制
版面配置階段遵循三步驟演算法,找出每個版面配置節點的寬度、高度和 x、y 座標:
- 測量子項:節點會測量子項 (如有)。
- 決定自己的大小:節點會根據這些測量結果決定大小。
- 放置子項:每個子節點都是根據節點本身的位置放置。
Constraints
可協助在演算法的前兩個步驟中,找出適合節點的大小。限制定義了節點寬度和高度的下限和上限。節點決定其大小時,測量到的大小應落在這個大小範圍內。
限制的類型
限制可以是下列其中一項:
- 有界限:節點的寬度和高度皆達到上限。
- 無限制:節點無大小限制。寬度和高度上限會設為無限大。
- 精確:節點必須遵循確切的大小規定。上下限設為相同的值。
- 組合:節點採用上述限制類型的組合。舉例來說,限制可以限定寬度,同時允許不受限的高度上限;您也可以設定確切的寬度,但提供固定的高度。
下一節將說明這些限制如何從父項傳遞至子項。
如何從父項傳遞至子項
在「版面配置階段的限制」一節中說明的演算法的第一個步驟中,限制會從 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
的原始圓形裁剪,因此輸出內容是非圓形的結果。