ConstraintLayout
ConstraintLayout 可以让组件相对屏幕或其他同级组件进行布局,可以减少 Row、Column、Box 布局的互相嵌套。
想要在项目中使用ConstraintLayout,必须在 app/build.gradle 中增加信赖
用法¶
- 通过 createRefs 或 createRefFor 创建引用,每一个组件需要有一个引用
- 通过 Modifier.constrainAs 关联引用
- 在 constrainAs 的 body 块中使用 linkTo 、centerVerticallyTo等设置约束
- parent 是默认的父组件的引用,可以直接使用
@Composable
fun ConstraintLayoutSample() {
var isChecked by remember {
mutableStateOf(false)
}
ConstraintLayout(
modifier = Modifier
.height(100.dp)
.fillMaxWidth()
.background(Color.Yellow)
) {
val (icon, primaryText, secondlyText, checkBox) = createRefs()
Icon(
imageVector = Icons.Default.AccountBox,
contentDescription = null,
modifier = Modifier.constrainAs(icon) {
top.linkTo(parent.top)
start.linkTo(parent.start, margin = 8.dp)
bottom.linkTo(parent.bottom)
})
Text(
"Primary Text",
fontSize = 25.sp,
fontWeight = FontWeight.Bold,
modifier = Modifier.constrainAs(primaryText) {
start.linkTo(icon.end, margin = 8.dp)
top.linkTo(parent.top)
})
Text("secondly text", modifier = Modifier.constrainAs(secondlyText) {
start.linkTo(primaryText.start)
top.linkTo(primaryText.top)
bottom.linkTo(parent.bottom)
})
Checkbox(
checked = isChecked,
onCheckedChange = { isChecked = it },
modifier = Modifier.constrainAs(checkBox) {
centerVerticallyTo(parent)
end.linkTo(parent.end)
})
}
}
解耦¶
在上面的例子中,我们可以看到约束直接写到组件代码之中,这样不容易让这个约束重复利用,因此我们把这些约束代码解耦出来。
所以我们可以使用另一种方案来实现
- 给 ConstraintsLayout 设置 ContraintSet
- 通过设置 layoutId 来关联组件
@Composable
fun ConstraintLayoutSample1() {
var isChecked by remember {
mutableStateOf(false)
}
LazyColumn() {
item {
ConstraintLayout(
modifier = Modifier
.height(100.dp)
.fillMaxWidth()
.background(Color.Yellow),
constraintSet = decoupledConstraints()
) {
Icon(
imageVector = Icons.Default.AccountBox,
contentDescription = null,
modifier = Modifier.layoutId("icon")
)
Text(
"Primary Text",
fontSize = 25.sp,
fontWeight = FontWeight.Bold,
modifier = Modifier.layoutId("primaryText")
)
Text("secondly text",
modifier = Modifier.layoutId("secondlyText"))
Checkbox(
checked = isChecked,
onCheckedChange = { isChecked = it },
modifier = Modifier.layoutId("checkBox")
)
}
}
}
}
private fun decoupledConstraints(): ConstraintSet {
return ConstraintSet {
val icon = createRefFor("icon")
val primaryText = createRefFor("primaryText")
val secondlyText = createRefFor("secondlyText")
val checkBox = createRefFor("checkBox")
constrain(icon) {
centerVerticallyTo(parent)
start.linkTo(parent.start, margin = 8.dp)
}
constrain(primaryText) {
start.linkTo(icon.end, margin = 8.dp)
top.linkTo(parent.top)
}
constrain(secondlyText) {
start.linkTo(primaryText.start)
bottom.linkTo(parent.bottom)
top.linkTo(primaryText.bottom)
}
constrain(checkBox) {
centerVerticallyTo(parent)
end.linkTo(parent.end)
}
}
}
这样,如果想重复使用这一组约束,就变得很简单了