Constraint Layout

Constraint Layout

温馨提示:本文最后更新于2025-12-12 11:32:21,某些文章具有时效性,若有错误或已失效,请在下方留言

ConstraintLayout 是一种高级布局系统,适合复杂 UI。可以在 Compose 中使用,用来创建:

  • 复杂对齐
  • 多视图相互依赖的布局
  • 百分比布局
  • 链式布局(Chains
  • Barrier(根据子项动态位置对齐)
  • Guideline(引导线)
  • 测量依赖(Dimension

基本使用

1. 添加依赖

// build.gradle.kts
implementation("androidx.constraintlayout:constraintlayout-compose:1.1.1")

依赖添加完后,点击 Sync Now 按钮。

2. 创建引用

@Composable
fun ConstraintLayoutScreen(modifier: Modifier = Modifier) {
    ConstraintLayout(modifier = Modifier.fillMaxWidth()) {
        // 1. 创建约束的引用
        // createRefs():为每个 Composable 生成唯一的引用(Reference),
        // 然后与 constrainAs 修饰符一起使用,为这些 Composable 指定约束。
        val (box1, box2, text) = createRefs()
    }
}

3. 设置约束

@Composable
fun ConstraintLayoutScreen(modifier: Modifier = Modifier) {
    ConstraintLayout(modifier = Modifier.fillMaxWidth()) {
        // 1. 创建约束的引用
        // createRefs():为每个 Composable 生成唯一的引用(Reference),
        // 然后与 constrainAs 修饰符一起使用,为这些 Composable 指定约束。
        val (box1, box2, text) = createRefs()

        // 2. 约束元素
        // 约束 Box1
        Box(
            modifier = Modifier
                .size(100.dp)
                .background(Color.Red)
                .constrainAs(box1) {
                    // constrainAs():允许你为某个 Composable 定义约束,
                    // 这些约束可以相对于其他 Composable,或相对于父布局来设置。

                    // 设置约束信息
                    top.linkTo(parent.top, margin = 100.dp)
                    start.linkTo(parent.start, margin = 40.dp)
                }
        )

        // 约束 Box2
        Box (
            modifier = Modifier
                .size(200.dp)
                .background(Color.Green)
                .constrainAs(box2) {
                    // 设置约束
                    top.linkTo(box1.bottom, margin = 20.dp)
                    start.linkTo(parent.start, margin = 30.dp)
                }
        )

        // 约束 Text
        Text(
            text = "Constraint Layout",
            modifier = Modifier.constrainAs(text) {
                // 设置约束
                top.linkTo(box2.bottom, margin = 16.dp)
                end.linkTo(parent.end, margin = 16.dp)
            }
        )
    }
}

运行效果,如下所示

运行效果
运行效果

Guidelines

ConstraintLayout 中,Guidelines(引导线) 是不可见的布局辅助工具,它们可以帮助你实现界面元素的精确定位与对齐。

Guidelines 充当布局中的参考线,使你能够将视图(Composable)定位到这些参考线的位置,而不仅仅是依赖父布局边缘或其他视图的位置。

一个 Guideline 可以是水平的(Horizontal)或垂直的(Vertical):

  • 垂直 Guideline(Vertical Guideline):自身宽度为 0,高度等于父级 ConstraintLayout 的高度
  • 水平 Guideline(Horizontal Guideline):自身高度为 0,宽度等于父级 ConstraintLayout 的宽度
@Composable
fun ConstraintLayoutScreen(modifier: Modifier = Modifier) {
    ConstraintLayout(modifier = Modifier.fillMaxWidth()) {
        // 1. 创建约束的引用
        // createRefs():为每个 Composable 生成唯一的引用(Reference),
        // 然后与 constrainAs 修饰符一起使用,为这些 Composable 指定约束。
        val (box1, box2, text) = createRefs()

        // Guidelines:通过将元素定位在父布局起始端或结束端的某个百分比位置,
        // 或固定距离处,帮助你创建一致且可适配的布局。
        val guideline1 = createGuidelineFromStart(0.15f)

        // 2. 约束元素
        // 约束 Box1
        Box(
            modifier = Modifier
                .size(100.dp)
                .background(Color.Red)
                .constrainAs(box1) {
                    // constrainAs():允许你为某个 Composable 定义约束,
                    // 这些约束可以相对于其他 Composable,或相对于父布局来设置。

                    // 设置约束信息
                    top.linkTo(parent.top, margin = 100.dp)
                    start.linkTo(guideline1)
                }
        )

        // 约束 Box2
        Box (
            modifier = Modifier
                .size(200.dp)
                .background(Color.Green)
                .constrainAs(box2) {
                    // 设置约束
                    top.linkTo(box1.bottom, margin = 20.dp)
                    start.linkTo(guideline1)
                }
        )

        // 约束 Text
        Text(
            text = "Constraint Layout",
            modifier = Modifier.constrainAs(text) {
                // 设置约束
                top.linkTo(box2.bottom, margin = 16.dp)
                start.linkTo(guideline1)
            }
        )
    }
}

运行效果,如下所示

运行效果
运行效果

Barrier

Barrier(障碍线) 是 ConstraintLayout 中一种“动态参考线”。
它会根据 多个元素的位置或尺寸 自动生成一条约束边界,让其他元素可以对齐在这条边界上。

Barrier 是另一种辅助组件。它接收多个视图作为输入,并根据这些引用视图中最“外侧”的那个,形成一条虚拟的参考线(Guideline)。

Guideline 类似,Barrier 也分为两种类型:

  • 垂直 Barrier(Vertical Barrier)
  • 水平 Barrier(Horizontal Barrier)

BarrierGuideline 的唯一区别是:

  • Barrier 的位置是动态的,会根据其内部多个 UI 元素的尺寸变化而改变,用于内容长度不确定;
  • Guideline 的位置是固定的(由百分比或固定距离决定,不会因内容变化而移动)。
@Composable
fun ConstraintLayoutScreen(modifier: Modifier = Modifier) {
    ConstraintLayout(modifier = Modifier.fillMaxWidth()) {
        // 1. 创建约束的引用
        // createRefs():为每个 Composable 生成唯一的引用(Reference),
        // 然后与 constrainAs 修饰符一起使用,为这些 Composable 指定约束。
        val (box1, box2, text) = createRefs()

        // Guidelines:通过将元素定位在父布局起始端或结束端的某个百分比位置,
        // 或固定距离处,帮助你创建一致且可适配的布局。
        val guideline1 = createGuidelineFromStart(0.15f)

        // Barriers:用于基于多个元素的边缘来创建约束。
        val barrier = createEndBarrier(box1, box2)

        // 2. 约束元素
        // 约束 Box1
        Box(
            modifier = Modifier
                .size(100.dp)
                .background(Color.Red)
                .constrainAs(box1) {
                    // constrainAs():允许你为某个 Composable 定义约束,
                    // 这些约束可以相对于其他 Composable,或相对于父布局来设置。

                    // 设置约束信息
                    top.linkTo(parent.top, margin = 100.dp)
                    start.linkTo(guideline1)
                }
        )

        // 约束 Box2
        Box (
            modifier = Modifier
                .size(200.dp)
                .background(Color.Green)
                .constrainAs(box2) {
                    // 设置约束
                    top.linkTo(box1.bottom, margin = 20.dp)
                    start.linkTo(guideline1)
                }
        )

        // 约束 Text
        Text(
            text = "Constraint Layout",
            modifier = Modifier.constrainAs(text) {
                // 设置约束
                top.linkTo(box2.bottom, margin = 16.dp)
                start.linkTo(barrier, margin = 16.dp)
            }
        )
    }
}

运行效果,如下所示

运行效果
运行效果

Chains

ConstraintLayout 中,Chain(链) 是一组相互依赖的元素,它们在水平或垂直方向上通过约束形成一种“链式布局”,可以控制元素在父布局中的分布方式。

Chain 类型

ChainStyle说明
Spread元素均匀分布,占满父布局
SpreadInside首尾元素贴边,中间元素均匀分布
Packed所有元素紧密堆积在一起,可用 bias 调整位

示例代码

@Composable
fun ConstraintLayoutScreen(modifier: Modifier = Modifier) {
    ConstraintLayout(modifier = Modifier.fillMaxSize()) {
        // 1. 创建约束的引用
        // createRefs():为每个 Composable 生成唯一的引用(Reference),
        // 然后与 constrainAs 修饰符一起使用,为这些 Composable 指定约束。
        val (box1, box2, text) = createRefs()

        // Guidelines:通过将元素定位在父布局起始端或结束端的某个百分比位置,
        // 或固定距离处,帮助你创建一致且可适配的布局。
        val guideline1 = createGuidelineFromStart(0.15f)

        // Barriers:用于基于多个元素的边缘来创建约束。
        val barrier = createEndBarrier(box1, box2)

        // 2. 约束元素
        // 约束 Box1
        Box(
            modifier = Modifier
                .size(100.dp)
                .background(Color.Red)
                .constrainAs(box1) {
                    // constrainAs():允许你为某个 Composable 定义约束,
                    // 这些约束可以相对于其他 Composable,或相对于父布局来设置。

                    // 设置约束信息
                    top.linkTo(parent.top, margin = 100.dp)
                    start.linkTo(guideline1)
                }
        )

        // 约束 Box2
        Box (
            modifier = Modifier
                .size(200.dp)
                .background(Color.Green)
                .constrainAs(box2) {
                    // 设置约束
                    top.linkTo(box1.bottom, margin = 20.dp)
                    start.linkTo(guideline1)
                }
        )

        // 约束 Text
        Text(
            text = "Constraint Layout",
            modifier = Modifier.constrainAs(text) {
                // 设置约束
                top.linkTo(box2.bottom, margin = 16.dp)
                start.linkTo(barrier, margin = 16.dp)
            }
        )

        // Chains
        createVerticalChain(box1, box2, chainStyle = ChainStyle.Spread)
    }
}

运行效果,如下所示

运行效果
运行效果
© 版权声明
THE END
喜欢就支持一下吧
点赞0赞赏 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容