在 Compose 中,UI 元素是以發出
UI 的一部分,然後會新增至顯示於
。每個 UI 元素都有一個父項,而且可能有多個子項。每項
元素也位於其父項中,並指定為 (x, y) 位置;
大小,指定為 width
和 height
。
父項會定義其子項元素的限制。元素會要求
超出這些限制的大小限制條件會用於限制
每個元素的 width
和 height
上限。如果元素含有子元素,
可能會測量每個子項以決定其大小。元素判定
就能定義子項
請參閱建立自訂元件
版面配置。
在 UI 樹狀結構中完成每個節點的版面配置需要三個步驟。每個節點都必須:
- 測量任何子項
- 決定其大小
- 放置其子項
使用範圍可定義「何時」可以測量及放置子項。
只有在測量和版面配置傳遞期間才能測量版面配置
且子項只能在版面配置期間 (且
)。由於 Compose 範圍的關係,
MeasureScope
、
和 PlacementScope
,
這會在編譯期間強制執行
使用版面配置修飾符
您可以使用 layout
修飾符修改元素的測量及配置方式
。Layout
是 lambda;參數包括您可以測量的元素
以 measurable
的形式傳遞,然後該可組合項的傳入限制,
constraints
。自訂版面配置修飾符的外觀如下:
fun Modifier.customLayoutModifier() = layout { measurable, constraints -> // ... }
假設在畫面中顯示 Text
,並控制從頂端到頂端之間的距離
新增文字的基準線這正是
paddingFromBaseline
修飾符的作用,這裡我們會以例子實作此修飾符。
方法是使用 layout
修飾符,以手動方式將可組合項放置在
。以下是當 Text
頂端邊框間距設為 24.dp
時的預期行為:
以下是產生此間距的程式碼:
fun Modifier.firstBaselineToTop( firstBaselineToTop: Dp ) = layout { measurable, constraints -> // Measure the composable val placeable = measurable.measure(constraints) // Check the composable has a first baseline check(placeable[FirstBaseline] != AlignmentLine.Unspecified) val firstBaseline = placeable[FirstBaseline] // Height of the composable with padding - first baseline val placeableY = firstBaselineToTop.roundToPx() - firstBaseline val height = placeable.height + placeableY layout(placeable.width, height) { // Where the composable gets placed placeable.placeRelative(0, placeableY) } }
以下程式碼的運作方式:
- 在
measurable
lambda 參數中,您可以測量Text
呼叫measurable.measure(constraints)
來呈現可評估參數 - 透過呼叫
layout(width, height)
來指定可組合項的大小 方法,因此也會提供用於放置已包裝元素的 lambda。於 在本例中,這是上一個基準及新增頂端邊框間距的高度。 - 您可以呼叫,將包裝的元素放到畫面中。
placeable.place(x, y)
。如果沒有放置包裝的元素,這些元素就不會放置。 顯示。y
位置與頂端邊框間距對應 - 文字的第一個基準線
如要驗證此設定是否正常運作,請在 Text
上使用修飾符:
@Preview @Composable fun TextWithPaddingToBaselinePreview() { MyApplicationTheme { Text("Hi there!", Modifier.firstBaselineToTop(32.dp)) } } @Preview @Composable fun TextWithNormalPaddingPreview() { MyApplicationTheme { Text("Hi there!", Modifier.padding(top = 32.dp)) } }
建立自訂版面配置
layout
修飾符只能變更呼叫的可組合函式。測量及版面配置
多個可組合函式,請改用 Layout
可組合函式。這個可組合函式
可讓您手動測量和調整子項的版面配置所有較高層級版面配置
例如 Column
和 Row
,是使用 Layout
可組合函式所建構。
我們來建立基本的 Column
版本。大部分自訂版面配置都會遵循以下格式
模式:
@Composable fun MyBasicColumn( modifier: Modifier = Modifier, content: @Composable () -> Unit ) { Layout( modifier = modifier, content = content ) { measurables, constraints -> // measure and position children given constraints logic here // ... } }
measurables
與 layout
修飾符類似,都是
需要測量,而 constraints
是父項的限制。
和先前的邏輯相同,MyBasicColumn
可像先前一樣實作
:
@Composable fun MyBasicColumn( modifier: Modifier = Modifier, content: @Composable () -> Unit ) { Layout( modifier = modifier, content = content ) { measurables, constraints -> // Don't constrain child views further, measure them with given constraints // List of measured children val placeables = measurables.map { measurable -> // Measure each children measurable.measure(constraints) } // Set the size of the layout as big as it can layout(constraints.maxWidth, constraints.maxHeight) { // Track the y co-ord we have placed children up to var yPosition = 0 // Place children in the parent layout placeables.forEach { placeable -> // Position item on the screen placeable.placeRelative(x = 0, y = yPosition) // Record the y co-ord placed up to yPosition += placeable.height } } } }
子項可組合項受 Layout
限制條件的限制 (沒有
minHeight
限制條件),而且其位置是根據 yPosition
先前的可組合函式
自訂可組合函式的運用方式如下:
@Composable fun CallingComposable(modifier: Modifier = Modifier) { MyBasicColumn(modifier.padding(8.dp)) { Text("MyBasicColumn") Text("places items") Text("vertically.") Text("We've done it by hand!") } }
版面配置方向
透過變更
LocalLayoutDirection
本機組合。
如果要在畫面中以手動方式放置可組合項,LayoutDirection
會是
是 layout
修飾符的 LayoutScope
或 Layout
可組合函式。
使用 layoutDirection
時,請使用 place
放置可組合函式。與
placeRelative
敬上
方法,place
不會根據版面配置方向變更
(從左到右或從右到左)。
實際操作自訂版面配置
如要進一步瞭解版面配置和修飾符,請參閱: Compose 的基本版面配置、 自訂版面配置的實際運作情形 建立自訂版面配置的 Compose 範例。
瞭解詳情
如要進一步瞭解 Compose 中的自訂版面配置,請參閱以下其他資源。
影片
為您推薦
- 注意:系統會在 JavaScript 關閉時顯示連結文字
- Compose 版面配置中的內建函式測量資料
- Compose 中的圖形
- Compose 修飾符