Compose中的布局

Compose中的布局线性布局Column和Row 竖直线性布局 API如下: 简单示例: 效果如下: 然后我们让内容显示在中间,添加如下代码: 效果如下: 水平

这是我参与8月更文挑战的第4天,活动详情查看:8月更文挑战

线性布局Column和Row

竖直线性布局

API如下:

inline fun Column( modifier: Modifier = Modifier, // 修饰符 verticalArrangement: Arrangement.Vertical = Arrangement.Top, // 类似于gravity,指定内容在垂直方向的位置 horizontalAlignment: Alignment.Horizontal = Alignment.Start, // 内容对齐方式,指定内容在水平方向的位置 content: @Composable ColumnScope.() -> Unit // 内容 )

简单示例:

@Composable
fun ColumnDemo() {
    Column(
        modifier = Modifier
            .size(width = 200.dp, height = 400.dp)
            .background(Color.Red),
    ) {
        Text(text = "text1")
        Text(text = "text2")
        Text(text = "text3")
    }
}

效果如下:

Column

然后我们让内容显示在中间,添加如下代码:

verticalArrangement = Arrangement.Center, // 指定垂直方向居中显示
horizontalAlignment = Alignment.CenterHorizontally // 指定水平方向居中对齐

效果如下:

Column内容居中

水平线性布局

API如下:

inline fun Row( modifier: Modifier = Modifier, 修饰符 horizontalArrangement: Arrangement.Horizontal = Arrangement.Start, // 类似于gravity,指定内容在水平方向的位置 verticalAlignment: Alignment.Vertical = Alignment.Top, // 内容对齐方式,只有垂直方向的,指定内容在垂直方向的位置 content: @Composable RowScope.() -> Unit // 内容 )

Row等价于横向的线性布局,跟Column用法类似,如下:

@Composable
fun RowDemo() {
    Row(
        modifier = Modifier
            .size(width = 200.dp, height = 400.dp)
            .background(Color.Red),
        verticalAlignment = Alignment.CenterVertically, // 垂直居中
        horizontalArrangement = Arrangement.SpaceBetween // 水平方向: 前后没有空隙,且子view之间均匀分散
    ) {
        // 添加背景来区分
        Text(text = "text1",modifier = Modifier.background(Color.Green))
        Text(text = "text1",modifier = Modifier.background(Color.Green))
        Text(text = "text1",modifier = Modifier.background(Color.Green))
    }
}

效果如下:

Row

Arrangement有如下枚举值:

Arrangement.Start // 子view排列在头部
Arrangement.End // 子view排列在尾部
Arrangement.Center // 子view排列在中间
Arrangement.SpaceBetween // 首尾没有空隙,且子view之间均匀分散
Arrangement.SpaceAround // 首尾空隙是每个子view之间空隙的一半
Arrangement.SpaceEvenly // 让每个子view之间的空隙均匀分散,包括首尾

其中SpaceBetween、SpaceAround、SpaceEvenly分别如下:

SpaceBetween SpaceAround SpaceEvenly

盒布局Box(帧布局)

API如下

inline fun Box( modifier: Modifier = Modifier, // 修饰符 contentAlignment: Alignment = Alignment.TopStart, // 内容对齐方式(水平和垂直),默认是左上角(LTR情况下) propagateMinConstraints: Boolean = false, // 是否将最小约束传给内部View,如果设置为true,则内容会填满Box本身 content: @Composable BoxScope.() -> Unit // 内部布局 )

简单示例:

@Composable
fun BoxDemo() {
    Box(
        modifier = Modifier
            .size(width = 200.dp, height = 200.dp)
            .background(Color.Red),
        contentAlignment = Alignment.Center, // 居中对齐
    ) {
        Text(
            text = "BoxLayout", modifier = Modifier
                .size(width = 100.dp, height = 100.dp)
                .background(Color.Green)
        )
    }
}

效果如下:

Box

现在我们添加如下代码:

propagateMinConstraints = true

发现Text填满了Box:

Box

约束布局ConstraintLayout

@Composable
fun ConstraintLayoutDemo(context: Context) {
    ConstraintLayout(
        modifier = Modifier
            .background(Color.Gray) // 添加灰色背景来区分
            .size(width = 300.dp, height = 500.dp) // 设置背景
    ) {
        // 创建两个id
        val (btn_click, text_hello) = createRefs()

        // 添加一个Button
        Button(
            onClick = { Toast.makeText(context, "Click Button", Toast.LENGTH_SHORT).show() },
            modifier = Modifier.constrainAs(btn_click) { // 指定id为btn_click
                top.linkTo(parent.top, margin = 32.dp)   // 顶部和父布局顶部对齐,同时设置margin为32dp
                start.linkTo(parent.start) // 左边和父布局左边对齐
                end.linkTo(parent.end)  // 右边和父布局右边对齐
                bottom.linkTo(text_hello.top) // 底部和text_hello顶部对齐
            }
        ) {
            Text(text = "Button")
        }

        // 添加一个Text
        Text(text = "Text",
            modifier = Modifier
                .background(Color.Red) //添加红色背景,方便区分
                .constrainAs(text_hello) { // 指定id为text_hello
                    top.linkTo(
                        btn_click.bottom,
                        margin = 48.dp
                    ) //  顶部和btn_click底部对齐,同时设置margin为48dp
                    start.linkTo(btn_click.start)
                    end.linkTo(btn_click.end)
                    bottom.linkTo(parent.bottom, margin = 32.dp) // 底部和parent底部对齐,同时设置margin为32dp
                })
    }
}

效果如下,完全符合预期:

约束布局

然后我们来看下ConstraintLayout其他的 边角API

1 GuideLine和Barrier

我们添加如下代码:

// 创建一个guideline,位于底部50%的位置
val line_bottom_50F = createGuidelineFromBottom(fraction = 0.5F)

val (tv_bottom) = createRefs()
// Text底部跟guideline对齐
Text(
    text = "Bottom_50",
    modifier = Modifier
        .background(Color.Yellow)
        .constrainAs(tv_bottom) {
            // 底部跟guideline对齐
            bottom.linkTo(line_bottom_50F)
        })

我们通过createGuidelineFromBottom()创建了一个从底部开始的GuideLine,参数可以是dp,也可以是浮点数,浮点数就是百分比,效果如下:

GuideLine

然后我们看下Barrier:

// 创建Barrier,参数为控件对应的id,尾部barrier位于两个控件的尾部
val barrier = createEndBarrier(btn_click, tv_bottom)

很简单,跟GuideLine没啥区别,参数就是想要编组的控件的id。用法就不再说了,跟GuideLine一样使用就行。

Tips:createGuideLineFromXXX/createXXXBarrier有很多基于方向的api,直接调用即可,而且借助GuideLine也能实现百分比布局。

2 Chain

Chain是ConstraintLayout的重点之一,它有两个api:

// 横向的Chain
createHorizontalChain()
// 竖向的Chain
createVerticalChain()

他们的第一个参数都是控件的id,第二个参数就是ChainStyle,分别是:

  • Packed: 所有控件挨在一起,居中
  • Spread: 所有控件均匀分布在父布局中,这是ChainStyle的默认值
  • SpreadInside: 第一个和最后一个控件分布在两端,其余平均分布在父布局中。

我们来看下Packed对应的效果:

// 创建引用(id)
var (tv_1, tv_2, tv_3) = createRefs()
// 创建Chain
val chain = createHorizontalChain(
    elements = arrayOf(tv_1, tv_2, tv_3), // 关联的id
    chainStyle = ChainStyle.Packed // 指定Chain类型
)

// 创建Chain关联的三个Text
Text(text = "tv1",modifier = Modifier.size(50.dp).background(Color.Red).constrainAs(tv_1){})
Text(text = "tv1",modifier = Modifier.size(50.dp).background(Color.Green).constrainAs(tv_2){})
Text(text = "tv1",modifier = Modifier.size(50.dp).background(Color.Yellow).constrainAs(tv_3){})

效果如下:

Packed

Spread的效果:

Spread

SpreadInside的效果:

SpreadInside

今天的文章Compose中的布局分享到此就结束了,感谢您的阅读。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/17337.html

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注