借助修饰符,您可以修饰或扩充可组合项。您可以使用修饰符来执行以下操作:
- 更改可组合项的大小、布局、行为和外观
- 添加信息,如无障碍标签
- 处理用户输入
- 添加高级互动,如使元素可点击、可滚动、可拖动或可缩放
修饰符是标准的 Kotlin 对象。您可以通过调用某个 Modifier
类函数来创建修饰符:
import androidx.compose.ui.Modifier
@Composable
private fun Greeting(name: String) {
Column(modifier = Modifier.padding(24.dp)) {
Text(text = "Hello,")
Text(text = name)
}
}
您可以将以下函数连在一起以将其组合起来:
@Composable
private fun Greeting(name: String) {
Column(modifier = Modifier
.padding(24.dp)
.fillMaxWidth()
) {
Text(text = "Hello,")
Text(text = name)
}
}
请注意,在上面的代码中,结合使用了不同的修饰符函数。
padding
在元素周围留出空间。fillMaxWidth
使可组合项填充其父项为它提供的最大宽度。
最佳做法是让所有可组合项接受 modifier
参数,并将该修饰符传递给其发出界面元素的第一个子项。这样做可以提高代码的可重用性,使其行为更可预测且更直观。如需了解详情,请参阅 Compose API 指南:接受元素和遵循修饰符参数。
修饰符顺序很重要
修饰符函数的顺序非常重要。由于每个函数都会对上一个函数返回的 Modifier
进行更改,因此顺序会影响最终结果。让我们来看看这方面的一个示例:
@Composable
fun ArtistCard(/*...*/) {
val padding = 16.dp
Column(
Modifier
.clickable(onClick = onClick)
.padding(padding)
.fillMaxWidth()
) {
// rest of the implementation
}
}
在上面的代码中,整个区域(包括周围的内边距)都是可点击的,因为 padding
修饰符应用在 clickable
修饰符后面。如果修饰符顺序相反,由 padding
添加的空间就不会响应用户输入:
@Composable
fun ArtistCard(/*...*/) {
val padding = 16.dp
Column(
Modifier
.padding(padding)
.clickable(onClick = onClick)
.fillMaxWidth()
) {
// rest of the implementation
}
}
内置修饰符
Jetpack Compose 提供了一个内置修饰符列表,可帮助您修饰或扩充可组合项。以下是一些用于调整布局的常见修饰符。
内边距和尺寸
默认情况下,Compose 中提供的布局会封装其子项。但是,您可以使用 size
修饰符设置尺寸:
@Composable
fun ArtistCard(/*...*/) {
Row(
modifier = Modifier.size(width = 400.dp, height = 100.dp)
) {
Image(/*...*/)
Column { /*...*/ }
}
}
请注意,如果指定的尺寸不符合来自布局父项的约束条件,则可能不会采用该尺寸。如果您希望可组合项的尺寸固定不变,而不考虑传入的约束条件,请使用 requiredSize
修饰符:
@Composable
fun ArtistCard(/*...*/) {
Row(
modifier = Modifier.size(width = 400.dp, height = 100.dp)
) {
Image(
/*...*/
modifier = Modifier.requiredSize(150.dp)
)
Column { /*...*/ }
}
}
在此示例中,即使父项的 height
设置为 100.dp
,Image
的高度还是 150.dp
,因为 requiredSize
修饰符优先级较高。
如果您希望子布局填充父项允许的所有可用高度,请添加 fillMaxHeight
修饰符(Compose 还提供了 fillMaxSize
和 fillMaxWidth
):
@Composable
fun ArtistCard(/*...*/) {
Row(
modifier = Modifier.size(width = 400.dp, height = 100.dp)
) {
Image(
/*...*/
modifier = Modifier.fillMaxHeight()
)
Column { /*...*/ }
}
}
如需在整个元素周围全添加内边距,请设置 padding
修饰符。
如需在文本基线上方添加内边距,以实现从布局顶部到基线保持特定距离,请使用 paddingFromBaseline
修饰符:
@Composable
fun ArtistCard(artist: Artist) {
Row(/*...*/) {
Column {
Text(
text = artist.name,
modifier = Modifier.paddingFromBaseline(top = 50.dp)
)
Text(artist.lastSeenOnline)
}
}
}
偏移量
要相对于原始位置放置布局,请添加 offset
修饰符,并在 x 轴和 y 轴中设置偏移量。偏移量可以是正数,也可以是非正数。padding
和 offset
之间的区别在于,向可组合项添加 offset
不会改变其测量结果:
@Composable
fun ArtistCard(artist: Artist) {
Row(/*...*/) {
Column {
Text(artist.name)
Text(
text = artist.lastSeenOnline,
modifier = Modifier.offset(x = 4.dp)
)
}
}
}
offset
修饰符根据布局方向水平应用。在从左到右的上下文中,正 offset
会将元素向右移,而在从右到左的上下文中,它会将元素向左移。如果您需要设置偏移量,而不考虑布局方向,请参阅 absoluteOffset
修饰符,其中,正偏移值始终将元素向右移。
Compose 中的类型安全
在 Compose 中,有些修饰符仅适用于某些可组合项的子项。例如,如果您希望使某个子项与父项 Box
同样大,而不影响 Box
尺寸,请使用 matchParentSize
修饰符。
Compose 通过自定义作用域强制实施此类型安全机制。例如,matchParentSize
仅在 BoxScope
中可用。因此,仅当在 Box
中使用子项时,才能使用此修饰符。
限定作用域的修饰符会将父项应知晓的关于子项的一些信息告知父项。这些修饰符通常称为“父项数据修饰符”。它们的内部构件与通用修饰符不同,但从使用角度来看,这些差异并不重要。
Box 中的 matchParentSize
如上所述,如果您希望子布局与父项 Box
尺寸相同而不影响 Box
的尺寸,请使用 matchParentSize
修饰符。
请注意,matchParentSize
仅在 Box
作用域内可用,这意味着它仅适用于 Box
可组合项的直接子项。
在以下示例中,子项 Spacer
从其父项 Box
获取自己的尺寸,在这种情况下,后者又会从其最大的子项 ArtistCard
中获取自己的尺寸。
@Composable
fun MatchParentSizeComposable() {
Box {
Spacer(Modifier.matchParentSize().background(Color.LightGray))
ArtistCard()
}
}
如果使用 fillMaxSize
代替 matchParentSize
,Spacer
将占用父项允许的所有可用空间,反过来使父项展开并填满所有可用空间。
Row 和 Column 中的 weight
如前文的内边距和尺寸部分所述,默认情况下,可组合项的尺寸由其封装的内容定义。您可以使用仅可在 RowScope
和 ColumnScope
中使用的 weight
修饰符,将可组合项的尺寸设置为可在其父项内灵活调整。
让我们以包含两个 Box
可组合项的 Row
为例。第一个框的 weight
是第二个框的两倍,因此其宽度也相差两倍。由于 Row
的宽度为 210.dp
,因此第一个 Box
的宽度为 140.dp
,第二个的宽度为 70.dp
:
@Composable
fun ArtistCard(/*...*/) {
Row(
modifier = Modifier.fillMaxWidth()
) {
Image(
/*...*/
modifier = Modifier.weight(2f)
)
Column(
modifier = Modifier.weight(1f)
) {
/*...*/
}
}
}
了解详情
我们提供了修饰符的完整列表及其参数和范围。