前言
在 Compose 中,Modifier 的调用顺序是有影响的。
修饰符列表
https://android-dot-google-developers.gonglchuangl.net/jetpack/compose/modifiers-list?hl=zh-cn
状态栏和底部导航栏
顶部状态栏
1 | .statusBarsPadding() |
底部导航栏
1 | .navigationBarsPadding() |
尺寸设置
固定大小
layout_width & layout_height
=> Modifier.size()
or (Modifier.width()
& Modifier.height()
)
size: 用于设置组件的固定大小。
1 | Modifier.size(width = 100.dp, height = 100.dp) |
自身大小
默认是 wrap_content
适配父大小
match_parent
=>
1 | .fillMaxWidth() |
fillMaxHeight()
修饰符的行为是占据其父组件分配给它的最大可用高度
具体表现取决于父组件的布局特性和其他同级组件的布局情况:
如果父组件是一个Column(垂直布局容器):
当 Column 使用默认的
Arrangement.Top
时,fillMaxHeight()
会让当前组件占据 Column 剩余的全部高度(即父组件高度减去前面同级组件占用的高度不考虑后面的组件
)当 Column 使用
Modifier.fillMaxHeight()
且设置verticalArrangement = Arrangement.SpaceEvenly
等分配方式时,会根据排列规则分配高度如果父组件是Box(层叠布局):
fillMaxHeight()
会让组件直接占据 Box 的全部高度,不受其他同级组件的影响(因为 Box 中的组件是层叠关系而非顺序排列)
剩余空间(权重)
权重只能在Row和Column中使用。
注意有多个元素,其中一个元素要占用剩余所有空间,这时候最好用.weight(1f)
因为
.fillMaxSize()
计算的时候是之前元素的剩余空间,如果有三个元素,中间的元素就会占用除下第一个元素后的所有空间,第三个元素就没法显示了。所以只有元素是最后一个元素的时候才能使用
.fillMaxSize()
,为了不出岔子都建议使用.weight(1f)
。
示例
1 | Column( |
背景
基本
1 | Modifier.background(Color.Green) |
背景渐变
1 | .background( |
渐变分割线
1 |
|
内外边距和背景
在 Compose 中,背景色使用 Modifier.background()
进行设置。
在 Compose 中,Margin 和 Padding 都用 Modifier.padding()
来设置。
- 没有
background
的时候是外边距
- 有
background
的时候在background
之前的是外边距
,在background
之后是内边距
示例:
1 | // 背景色不包括 padding 的部分,效果类似 margin |
background 还可以传入 shape 参数,来设置不同的背景形状。
Shape 对象也是一个通用的能力,例如,可以用于 clip 当中,进行裁切。
阴影
设置
1 | .padding(10.dp) |
注意
shadow
设置要在尺寸之后,要在background
之前。不能和
clip
搭配,会把阴影剪裁掉,设置shadow
会自动剪裁背景。最开始要设置
padding
,这样会给阴影预留空间。
Card阴影
1 | Card( |
offset
offset: 用于将组件从其默认位置移动指定的偏移量。
偏移的元素不会影响后续元素的位置,相当于只是视觉上位置变了,实际位置没变。
1 | Modifier.offset(x = 20.dp, y = 20.dp) |
pading和offset
先看一个示例
1 | Row( |
如上
红色和绿色的图形都偏移了相同的位置,并且大小是一样的。
padding是比较特殊的,它放在不同的位置的含义是不一样的
- 在size前不会影响组件大小和背景一样大、相当于css中的margin。
- 在size后背景前会压缩背景的大小。
- 在背景后相当于css中的padding。
- 当作用是margin的时候会影响后续元素的位置。
offset相当于偏移
- 在Box中偏移值就相当于绝对定位。
- 在Row/Column中会相对于原位置偏移。
- 偏移的元素不会影响后续元素的位置。
裁剪
clip: 用于裁剪组件的内容,以匹配指定的形状。
1 | Modifier.clip(shape = CircleShape) |
注意
剪裁要放在
background
之前,否则背景不会被剪裁。
背景裁剪:只能通过设置背景形状实现。
1 | Modifier |
边框(border)
border: 用于向组件添加边框。
1 | Modifier.border(width = 2.dp, color = Color.Black) |
圆形边框
1 | Box( |
这点要注意的是
必须要先调用
clip
,再设置背景background
,否则背景不会被剪裁,跟我们的直觉是相反的。
渐变边框
系统属性
1 | .border( |
注意
Offset
的值不是0f
到100f
,是0f
到Float.POSITIVE_INFINITY
自己绘制
1 | import androidx.compose.foundation.layout.Box |
使用
1 | GradientBorderBox( |
透明度
1 | Modifier.alpha(0.5f) |
对齐
内部对齐
Box
1 | contentAlignment = Alignment.Center |
Row
1 | verticalAlignment = Alignment.Top |
Column
1 | horizontalAlignment = Alignment.Start |
子相对父对齐
align: 用于指定组件在其父容器中的对齐方式。
align
方法用于指定组件在其父容器中的对齐方式。它适用于容器类组件,如 Box
、Column
、Row
等,以及具有布局属性的组件,如 BoxWithConstraints
。
设置组件内的元素的对齐方式不能用Modifier
,会有专门的属性来配置。
align
方法生效的情况取决于父容器的布局方式。
通常情况下,父容器需要使用相应的布局修饰符,如 Box
中的 BoxScope
、Column
中的 ColumnScope
或 Row
中的 RowScope
。
1 | Box( |
Column中使用:
1 | Column( |
事件
clickable: 用于使组件可点击,并指定点击事件的处理程序。
1 | Modifier.clickable(onClick = { /* 点击事件处理 */ }) |
pointerInput: 用于处理指针输入事件,例如触摸或鼠标事件。
1 | Modifier.pointerInput { /* 处理指针输入事件的逻辑 */ } |
文字大小
文字大小使用函数参数(fontSize)设置,而不是 Modifier
颜色转换
1 | import androidx.compose.ui.graphics.Color |