compose布局学习总结

一、标准布局

  1. 标准布局组件

Column 行  相当于LinearLayout vertical方向

row 列 相当于LinearLayout horizontal方向

BOX 相当于FrameLayout 需要明确的指出控件的具体位置

Surface可以设置一个形状然后再包裹对应的控件如设置一个圆形的图片

Surface(modifier = Modifier.size(50.dp),shape = CircleShape) {
    Image()
}

 2.修饰符(modifier) > 修饰符是具有顺序的(如marage可以使用padding来代替 先进行一次padding然后设置背景在设置一次padding,背景不会包含第一次的padding)

 3.slots API 可以设置标题菜单栏等 如TopAppBar

4.列表

 1.布局可以通过设置verticalScroll和horizontalScroll来使它进行滚动相当于ScrollView

 2.LazyColumn和LazyRow是可以懒加载的列表只加载显示的部分 相当于Recyclerview

二、自定义布局

1.对于单个控件可以在修饰符layout中进行自定义使用measurable.measure(constraints) 进行一次测量拿到尺寸的具体属性并重新设置控件的宽高,然后再layout中设置显示内容的开始位置

Text(modifier = Modifier.firstBaselineToTop(24.dp))

fun Modifier.firstBaselineToTop(firstBaselineToTop: Dp) = this.then(
    layout { measurable, constraints ->
        //测量元素
        val placeable = measurable.measure(constraints)
        //测量之后,获取元素的高度
        val firstBaseline = placeable[FirstBaseline]
        //计算元素的新Y
        val placeableY = firstBaselineToTop.roundToPx() - firstBaseline
        val height = placeable.height + placeableY
        layout(placeable.width,height){

//设置显示的位置
            placeable.placeRelative(0,placeableY)
        }
    }
)
  1. 对于多个控件则直接在@Composable方法体内的Layout方法中进行重新排列绘制相对于上面的单个控件这里返回的是measurables, constraints都是集合

MyOwnColum (){
    Text("MyOwnColum")
    Text("places items")
    Text("vertically")
    Text("we've done it by hand!")
}

@Composable
fun MyOwnColum(modifier: Modifier = Modifier,content: @Composable () -> Unit) {
    Layout(modifier = modifier, content = content){ measurables, constraints ->
        //测量的元素集合
        val placeables = measurables.map { measurable->
            measurable.measure(constraints)
        }
        var yPosition = 0
        //布局的大小
        layout(constraints.maxWidth, constraints.maxHeight) {
            placeables.forEach{ placeable ->
                placeable.placeRelative(0,yPosition)

//累加Y 这样就是一行一行显示
                yPosition += placeable.height
            }
        }
    }
}

三、约束布局

(ConstraintLayout 相当于RelativeLayout 设置约束有点像IOS)

1.不是标准布局控件所以需要导入相应的支持

implementation("androidx.constraintlayout:constraintlayout-compose:1.1.1")

 2.使用createRefs创建约束属性在修饰符在constrainAs方法内使用linkTo方法创建约束

ConstraintLayout {
    val (button,text) = createRefs()
    Button(onClick = {}, modifier = Modifier.constrainAs(button){
        top.linkTo(parent.top, margin = 16.dp)
    }) {
        Text("button")
    }
    Text(text = "Text", modifier = Modifier.constrainAs(text){
        top.linkTo(button.bottom, margin = 16.dp)
        centerHorizontallyTo(parent)
    })
}

3.可以使用ConstraintSet方法将一些约束提取出来,并在ConstraintLayout 方法上进行设置,控件在修饰符上使用layoutId指定标识

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 = margin)
        }
    }
}



BoxWithConstraints {
    val constraints = if (maxWidth < maxHeight) {
        decoupledConstraints(16.dp)
    }else{
        decoupledConstraints(160.dp)
    }
    ConstraintLayout(constraints) {
        Button(onClick = {}, modifier = Modifier.layoutId("button")) {
            Text("button")
        }

        Text(text = "Text", modifier = Modifier.layoutId("text"))
    }
}

四、Intrinsics

可以在布局中去指定测量的时候按最大或者最小值去测量,如下面的分隔线设置的是最大宽度,当时布局中使用intrinsics指定测量按满足子控件的最大宽度显示

Row(modifier =  modifier.height(IntrinsicSize.Min)) {
    Text(
        "Hi", modifier = Modifier
            .weight(1f)
            .padding(start = 4.dp)
            .wrapContentWidth(Alignment.Start)
    )

    VerticalDivider(color = Color.Black, modifier = Modifier
        .fillMaxHeight()
        .width(1.dp))

    Text(
        "there", modifier = Modifier
            .weight(1f)
            .padding(start = 4.dp)
            .wrapContentWidth(Alignment.End)
    )
}

其他

image组件可以导入implementation("io.coil-kt:coil-compose:1.3.0")直接加载网络图片

Image(painter = rememberImagePainter(data = "URL"),contentDescription = null)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值