Modifier
大家对修饰符Modifier应该很熟悉了,前面Column、Row、Box和Text等都用到了这个修饰符,它是一个有序的、不可变的修饰元素集合,用于给Compose UI元素添加装饰、行为,如background、padding、点击事件等,或者给Text设置单行、给Button设置各种点击状态等行为。
Modifier非常强大,你能想到的操作它基本都可以实现,包括滚动、拖动、缩放等,它的东西比较多,我们从几种常用的修饰符功能。
内边距padding
Modifier可以修改内边距,就是padding,如:
Text("程序员", modifier = Modifier.padding(20.dp))
复制代码
可以看到Modifier来添加内边距,只需要调用padding方法传入对应的边距值即可。先看看padding的源码是怎么定义的:
@Stable
fun Modifier.padding(
start: Dp = 0.dp,
top: Dp = 0.dp,
end: Dp = 0.dp,
bottom: Dp = 0.dp
)
@Stable
fun Modifier.padding(
horizontal: Dp = 0.dp,
vertical: Dp = 0.dp
)
@Stable
fun Modifier.padding(all: Dp)
复制代码
我们可以看到padding有多种设置方式,可以单独设置一边,也可以设置横向纵向,还可以统一设置所有的。上面的实例代码默认设置上下左右所有的内边距:
设置控件的尺寸
我们之前的实例代码中是怎么设置尺寸的?Android View中直接可以在xml布局里写死宽高,也可以自适应或者充满父布局:
<TextView
android:layout_width="100dp"
android:layout_height="40dp"
android:gravity="center"
android:text="Text1"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:text="Text2"/>
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:text="Text3"/>
复制代码
那么Compose中,前面的示例中也有用到,如充满父布局:
Text("程序员", modifier = Modifier.fillMaxSize())
复制代码
或者也可以只充满宽或者高:
Text("程序员", modifier = Modifier.fillMaxWidth()) // 充满宽
Text("程序员", modifier = Modifier.fillMaxHeight()) // 充满高
复制代码
当你什么都不做的时候,就是默认的自适应大小,如Android View中的Wrap_content。如果我们想设置固定值大小的话可以这样:
Text("程序员", modifier = Modifier.size(100.dp)) // 宽高都是100dp
Text("程序员", modifier = Modifier.size(width = 100.dp, height = 80.dp)) // 宽100dp 高80dp
复制代码
如果希望子布局的尺寸设置为父控件Box相同,但是不影响Box的尺寸大小,我们可以使用matchParentSize修饰符。matchParentSize仅在Box作用域内可用,意味着它仅适用于Box可组合项的直接子项。我们看个例子,内部Spacer从其父控件Box获取自己的尺寸,而后者又从其包含的Text获取自己的尺寸:
Box {
Spacer(modifier = Modifier.matchParentSize().background(Color.Red))
Text("程序员", fontSize = 30.sp)
}
复制代码
Row和Column中的Weight修饰符
在Android View中线性布局也经常用weight,在Compose中我们是这么用weight的:
Row(
Modifier
.fillMaxSize()
.padding(10.dp)) {
Box(modifier = Modifier.weight(2f).height(50.dp).background(Color.Blue))
Box(modifier = Modifier.weight(1f).height(50.dp).background(Color.Red))
}
复制代码
可以看出,宽度蓝色:红色是2:1,正好是我们设置的对应weight的比例大小。
控件添加点击事件
Android中我们通过控件view.setOnClickListener来设置点击事件,Compose中Modifier可以设置点击事件:
Row(
Modifier
.fillMaxSize()
.padding(10.dp)) {
Box(modifier = Modifier.weight(2f).height(50.dp).background(Color.Blue))
Box(modifier = Modifier.weight(1f).height(50.dp).background(Color.Red).clickable {
Log.e("LM" , "点击了Box")
})
}
// 点击红色Box后可以在控制台看到日志:
// 2022-04-04 15:08:52.793 19862-19862/com.carey.compose E/LM: 点击了Box
复制代码
控件添加圆角
Android View中实现圆角我们都是定义shape.xml,或者通过自定义控件通过canvas等去实现。但是在Compose中还是很容易的。用Modifier.shadow:
@Suppress("UnnecessaryComposedModifier")
@Stable
fun Modifier.shadow(
elevation: Dp, // 阴影的高度
shape: Shape = RectangleShape, // shape
clip: Boolean = elevation > 0.dp // 是否裁剪其内容
) // 省略...
复制代码
我们看到它只有三个参数,第一个参数是设置阴影的高度,类型为Dp,直接设置即可;第二个参数是shape,想设置圆角的话,通过它即可实现;第三个参数是clip,是否裁剪其内容,默认根据阴影高度来判断,如:
Box(contentAlignment = Alignment.Center) {
Image(painter = painterResource(id = R.drawable.small),
// modifier = Modifier.size(150.dp).shadow(elevation = 10.dp, shape = MaterialTheme.shapes.medium),
modifier = Modifier.size(150.dp).shadow(elevation = 10.dp, shape = RoundedCornerShape(18.dp)), // 指定圆角大小值
contentDescription = ""
)
}
复制代码
如果不想要阴影,可以把elevation值设置成0,然后手动打开裁剪clip属性即可:
Box(contentAlignment = Alignment.Center) {
Image(painter = painterResource(id = R.drawable.small),
// modifier = Modifier.size(150.dp).shadow(elevation = 10.dp, shape = MaterialTheme.shapes.medium),
modifier = Modifier.size(150.dp).shadow(elevation = 0.dp, shape = RoundedCornerShape(18.dp), clip = true),
contentDescription = ""
)
}
复制代码
Modifier.shadow不只可以给Image设置圆角,其它可组合项也可以设置圆角。后期我们会介绍复杂的控件等。