在研究 Compose 元件時,讀者應該有發現,每個元件都有 modifier
這個參數,有時要改變元件的外觀或行為時,就得透過這個參數。但到底 Modifier
是什麼,總覺得有點霧裡看花的感覺。今天的耕讀筆記,就要來好好研究一下在 Compose 裡很重要的 Modifier
。
Modifier
根據 Jetpack Compose 官方文件,Modifier
可以用在 @Composable
的幾個地方:
在使用 Modifier
時,有幾個值得注意的特點:
Modifier
是標準的 Kotlin Object,使用時直接以 Object 操作即可。Modifier
Object 的方法設計支援 Method Chain,開發者可串接多個方法,一次設定多個屬性。Modifier
方法時,順序是有意義的,在使用上要注意呼叫的順序。Modifier
設定背景顏色及不透明度(background()
、alpha()
)Modifier
可設定元件的背景顏色(如 Box
或 Text
等元件),透過 background()
方法,可以指定顏色(color
)、形狀(shape
)及不透明度(alpha
)。
Text(
text = "...",
modifier = Modifier.background(Color.Green),
)
為元件上背景色時,不止可以填單色,還可以用 brush
參數設定漸層色。
val verticalGradientBrush = Brush.verticalGradient(
colors = listOf(
Color.Red,
Color.Yellow,
Color.White
)
)
Box(
Modifier.size(100.dp).background(brush = verticalGradientBrush)
)
Modifier
也能用於改變元件的不透明度,透過 alpha()
方法,傳入 0
到 1
之間的 Float 數值,0
表示全透明、1
表示不透明。
Text(
text = "...",
modifier = Modifier.alpha(0.6f),
)
Modifier
設定邊框(border()
)Modifier
提供 border()
方法,可用於設定元件的邊框,透過寬度(width
)、顏色或筆刷(color
或 brush
)及形狀(shape
)的設定,就可以幫一段文字增加 2dp 綠色圓角矩形的邊框:
Text(
text = "...",
modifier = Modifier
.padding(10.dp)
.border(2.dp, SolidColor(Color.Green), RoundedCornerShape(20.dp))
.padding(10.dp)
)
Modifier
設定裁剪(clip()
)Compose 也支援用 Modifier
對物件做截剪,比方說在 UI 上有一個使用者大頭照,原本照片是正方形的,若我們想做出圓形的裁剪,就可以用 clip()
來實作:
Image(
painter = painterResource("..."),
contentDescription = "...",
modifier = Modifier.clip(CircleShape)
)
Compose 支援以下這些形狀的裁剪:
RectangleShape
CircleShape
RoundedCornerShape
CutCornerShape
Modifier
設定間距(padding()
)在寫 UI 時,其實元件與元件之間會有一個隱形的間距,有寫 CSS 經驗的讀者,就知道要設定 Margin 及 Padding。有別於 CSS 這種區分內距及外距的設計,在 Compose 裡只有 padding()
,根據它在方法串接的位置發揮不同的效果。
Box(
modifier = Modifier
.padding(8.dp)
.border(
width = 2.dp,
color = Color.Red,
shape = RoundedCornerShape(2.dp)
)
.padding(8.dp),
) {
Box(
modifier = Modifier.size(width = 100.dp, height = 10.dp)
.background(Color.Red),
)
}
在上面的例子裡,在 Box
裡放了另一個 Box
,外層的 Box
用 border()
做了一個紅色的圓角矩形外框,在設定邊框的前後加上了 padding()
,第一個 padding()
設定的是外距,也就是 Margin,第二個 padding()
則是設定內距,也就是以往經驗裡認知的 Padding。
Modifier
設定尺寸(width()
、height()
、size()
)在排版 UI 元件時,很常會需要設定元件尺寸,Modifier
有數個跟尺寸有關的方法可以讓開發者調整元件的寬、高:
width()
可以指定元件的寬度,單位用 dp
。height()
可以指定元件的高度,單位用 dp
。size()
,單位用 dp
。不過 size()
方法也可以傳入兩個參數,分別指定寬高。Box(
modifier = Modifier.size(50.dp)
) {
// ...
}
Box(
modifier = Modifier.width(50.dp).height(100.dp)
) {
// ...
}
Box(
modifier = Modifier.size(50.dp)
) {
// ...
}
Box(
modifier = Modifier.size(width = 50.dp, height = 100.dp)
) {
// ...
}
除了指定固定的寬高之外,Compose 也支援另外三種自動撐大元件的設定:fillMaxZie()
會將元件上下左右撐到大父元素的大小、fillMaxWidth()
只會撐大寬度到父元素的大小、fillMaxHeight()
則會撐大高度到父元素的大小。
Box(
modifier = Modifier.fillMaxSize(),
) {
// ...
}
Box(
modifier = Modifier.fillMaxWidth(),
) {
// ...
}
Box(
modifier = Modifier.fillMaxHeight(),
) {
// ...
}
Modifier
設定旋轉及縮放(rotate()
、scale()
)Modifier
還可以用於設定元件的旋轉及縮放。rotate()
傳入 0
至 359
的 Float 整數可以讓元件以順時針旋轉,若傳入的是負值,則以逆時針旋轉。scale()
方法則是依傳入的 Float 數值放大元件,放大時可用 scale(scaleX = 2f, scaleY = 3f)
分別指定長寬的放大比例
Image(
painter = painterResource("kotlin-logo.png"),
contentDescription = "Kotlin Logo",
modifier = Modifier.rotate(15f).scale(1.5f)
)
Modifier
設定事件(clickable()
)Modifier
神奇之處在於還能讓原本沒有事件反應的元件能綁定事件,透過 clickable()
綁定 Event Handler 後 就能讓元件跟使用者互動。
val rotateDegree = remember { mutableStateOf(0f) }
Image(
painter = painterResource("kotlin-logo.png"),
contentDescription = "Kotlin Logo",
modifier = Modifier.clickable {
rotateDegree.value = rotateDegree.value + 15f
}.rotate(rotateDegree.value)
)
在上面的例子裡,我們在 Image
綁定了 clickable()
,每次點擊圖片時就更改旋轉角度 15 度。透過這麼簡單的設定,這個圖片就可以跟使用者做出滑鼠互動了!