今天大概會聊到的範圍
- basic layout
- arrangement & alignment
在 Compose 之中,我們有三個可以乘載其他 component 的基礎 container。他們分別是縱向排列的 Column
、橫向排列的 Row
以及圖層式排列的 Box
。透過這三個 container,我們可以擺出各式各樣的畫面。
(image source: Compose layout basics | Android Developers)
在擺放 Layout 時,大致可以透過兩個面向來異動 component 在 container 中的位置:
很類似原本的 xml 排版中, gravity
和 layout_gravity
這兩個 attribute 的行為。
註:這邊會用 container 來代表在 Row / Column 這種可以裝其他 composable 的 composable。而裝在內 composable 則的會用 item 來稱呼。
以 Row 舉例,Row 中的 item 會是橫向排列。不同的 item 的高度不同時,就有怎麼對齊的問題。
透過 Row 的 verticalAlignment
這個參數,可以定義對齊方式。
常見的有對齊方式有:Alignment.Bottom
, Alignment.Top
和 Alignment.CenterVertically
@Preview
@Composable
fun `Row Alignment Bottom`() {
Row(
verticalAlignment = Alignment.Bottom, // <<<
modifier = Modifier
.height(130.dp)
.fillMaxWidth()
) {
ChildA()
ChildB()
ChildC()
}
}
Alignment.Bottom | Alignment.CenterVertically | Alignment.Top |
---|---|---|
另外,還可以透過 BiasAlignment.Vertical(bias)
在 1 ~ -1 之間的某一個特定比例做對齊 ( -1 = Top , 1 = Bottom, 0 = Center )
@Preview
@Composable
fun `Row Alignment Bias Vertical`() {
Row(
verticalAlignment = BiasAlignment.Vertical(-0.4f),
modifier = Modifier
.height(130.dp)
.fillMaxWidth()
) {
ChildA()
ChildB()
ChildC()
}
}
BiasAlignment.Vertical |
---|
除了 Alignment 外,還有 Arrangement ,Arrangment 調整的是 item 在 container 擺放的位置。最基本的是 Start
、End
,代表著 item 從 container 中最左 or 最右開始擺放。Center
則是代表所有 item 集合在最中間
@Preview
@Composable
fun `Row Arrangement Start`() {
Row(
horizontalArrangement = Arrangement.Start, // <<<
modifier = Modifier
.height(130.dp)
.fillMaxWidth()
) {
ChildA()
ChildB()
ChildC()
}
}
Arrangement.Start | Arrangement.End | Arrangement.Center |
---|---|---|
另外,還有 SpaceEvently
, SpaceBetween
和 SpaceAround
三種設定可以將物件平均分佈在 container 內。
SpaceEvently
就是普通的平均分佈。SpaceBetween
也是平均分佈,但是兩端不留空間。最後 SpaceAround
是每個 item 的兩邊都有一個間隔,意味著 item 與 item 間的空間會是最兩端 item 與 container 邊界間的兩倍
Arrangement.SpaceEvently | Arrangement.SpaceBetween | Arrangement.SpaceAround |
---|---|---|
Column 也有完全相同的結構只是方向改成垂直的,這邊就不多做介紹。
有時候,我們只需要某一個 item 擺在特殊的位置,這時候可以對特定 item 設定 align 這個 modifier 。align 在對應的 container 中能使用的參數與稍早提到的 alignment 參數是相同的。在 Row
中可以使用 Top
/ Bottom
/ CenterVertically
、Column
中可以做 Start
/ End
/ CenterHorizontally
。在 Box
中擺放的位置更自由,有上下左右、四角及中間等九個位子(如下圖)。當然,前面提到的 BiasAlignment
也是可以使用的。
@Preview(group = "item arrangement")
@Composable
fun `Arrangement Item`() {
Box(
modifier = Modifier.size(360.dp)
) {
Item(name = "TopStart", modifier = Modifier.align(Alignment.TopStart))
Item(name = "TopCenter", modifier = Modifier.align(Alignment.TopCenter))
Item(name = "TopEnd", modifier = Modifier.align(Alignment.TopEnd))
Item(name = "CenterStart", modifier = Modifier.align(Alignment.CenterStart))
Item(name = "Center", modifier = Modifier.align(Alignment.Center))
Item(name = "CenterEnd", modifier = Modifier.align(Alignment.CenterEnd))
Item(name = "BottomStart", modifier = Modifier.align(Alignment.BottomStart))
Item(name = "BottomCenter", modifier = Modifier.align(Alignment.BottomCenter))
Item(name = "BottomEnd", modifier = Modifier.align(Alignment.BottomEnd))
}
}
有了這些調整位置的方式、基本的 padding、再加上對 Layout 的嵌套,已經可以大致排出各種需求了。