舉個(gè)??
@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()
}
}
- 創(chuàng)建引用墨叛,
createRefs()
,也就是定義我們需要使用那個(gè)控件 - 使用
constrainAs
修飾符提供約束,該修飾符將引用作為參數(shù)懊纳,并允許在 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 - 布局是包裝內(nèi)容,受該約束限制闺兢。
wrapContent - 即使約束不允許茂缚,布局也是包裝內(nèi)容。
fillToConstraints - 布局將擴(kuò)展以填充由其約束定義的空間。
preferredValue - 布局是一個(gè)固定的 dp 值脚囊,受該約束影響龟糕。
value - 布局是一個(gè)固定的 dp 值,無(wú)論該約束如何
@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
}
)
}
}
解耦A(yù)PI
在示例中悔耘,約束已被內(nèi)聯(lián)指定讲岁,并在應(yīng)用它們的可組合中使用修飾符。 但是淮逊,在某些情況下催首,將約束與其應(yīng)用的布局解耦是有價(jià)值的:常見(jiàn)示例是根據(jù)屏幕配置輕松更改約束或在 2 個(gè)約束集之間設(shè)置動(dòng)畫(huà)。
@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)
}
}
}