JetPack Compose 基础(2)之 Constrain
2021-09-09 本文已影响0人
zcwfeng
举个🌰
@Composable
fun ConstraintLayoutContent() {
ConstraintLayout {
// Create references for the composables to constrain
val (button, text) = createRefs()
Button(
onClick = { /* Do something */ },
// Assign reference "button" to the Button composable
// and constrain it to the top of the ConstraintLayout
modifier = Modifier.constrainAs(button) {
top.linkTo(parent.top, margin = 16.dp)
start.linkTo(parent.start,margin = 10.dp)
}
) {
Text("Button")
}
// Assign reference "text" to the Text composable
// and constrain it to the bottom of the Button composable
Text("Text", Modifier.constrainAs(text) {
top.linkTo(button.bottom, margin = 16.dp)
})
}
}
@Preview(
showBackground = true,
backgroundColor = 0xfff
)
@Composable
fun ConstraintLayoutContentPreview() {
Compose_studyTheme {
ConstraintLayoutContent()
}
}
- 创建引用,
createRefs()
,也就是定义我们需要使用那个控件 - 使用
constrainAs
修饰符提供约束,该修饰符将引用作为参数,并允许在 lambda 体中指定其约束。 - linkTo 指定约束,类比 XML 使用ConstraintLayout的约束 top_to_top等
linkTo(parent.top, margin = 16.dp)
修改上面的例子,ConstraintLayout其他用法
@Composable
fun ConstraintLayoutContent() {
ConstraintLayout {
// Create references for the composables to constrain
val (button1,button2, text) = createRefs()
Button(
onClick = { /* Do something */ },
// Assign reference "button" to the Button composable
// and constrain it to the top of the ConstraintLayout
modifier = Modifier.constrainAs(button1) {
top.linkTo(parent.top, margin = 16.dp)
}
) {
Text("Button 1")
}
// Assign reference "text" to the Text composable
// and constrain it to the bottom of the Button composable
Text("Text", Modifier.constrainAs(text) {
top.linkTo(button1.bottom, margin = 16.dp)
centerAround(button1.end)
})
val barrier = createEndBarrier(button1, text)
Button(
onClick = { /* Do something */ },
modifier = Modifier.constrainAs(button2) {
top.linkTo(parent.top, margin = 16.dp)
start.linkTo(barrier)
}
) {
Text("Button 2")
}
}
}
自定义尺寸
可用 Dimension 行为属性:
preferredWrapContent - 布局是包装内容,受该约束限制。
wrapContent - 即使约束不允许,布局也是包装内容。
fillToConstraints - 布局将扩展以填充由其约束定义的空间。
preferredValue - 布局是一个固定的 dp 值,受该约束影响。
value - 布局是一个固定的 dp 值,无论该约束如何
@Composable
fun LargeConstraintLayout() {
ConstraintLayout {
val text = createRef()
val guideline = createGuidelineFromStart(fraction = 0.5f)
Text(
"This is a very very very very very very very long text",
// Modifier.constrainAs(text) {
// linkTo(start = guideline, end = parent.end)
// }
Modifier.constrainAs(text) {
linkTo(guideline, parent.end)
width = Dimension.preferredWrapContent
}
)
}
}
解耦API
在示例中,约束已被内联指定,并在应用它们的可组合中使用修饰符。 但是,在某些情况下,将约束与其应用的布局解耦是有价值的:常见示例是根据屏幕配置轻松更改约束或在 2 个约束集之间设置动画。
@Preview(showBackground = true, backgroundColor = 0xfff)
@Composable
fun DecoupledConstraintLayout() {
BoxWithConstraints {
val constraints = if (maxWidth < maxHeight) {
decoupledConstraints(margin = 16.dp) // Portrait constraints
} else {
decoupledConstraints(margin = 32.dp) // Landscape constraints
}
ConstraintLayout(constraints) {
Button(
onClick = { /* Do something */ },
modifier = Modifier.layoutId("button")
) {
Text("Button")
}
Text("Text", Modifier.layoutId("text"))
}
}
}
private fun decoupledConstraints(margin: Dp): ConstraintSet {
return ConstraintSet {
val button = createRefFor("button")
val text = createRefFor("text")
constrain(button) {
top.linkTo(parent.top, margin= margin)
}
constrain(text) {
top.linkTo(button.bottom, margin)
}
}
}