JetpackPack 知识Android 知识

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()
    }
}
  1. 创建引用,createRefs(),也就是定义我们需要使用那个控件
  2. 使用 constrainAs修饰符提供约束,该修饰符将引用作为参数,并允许在 lambda 体中指定其约束。
  3. 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)
        }
    }
}
上一篇下一篇

猜你喜欢

热点阅读