我在前面的文章中介绍了一些compose的基础,但是很显然还不能够应用到开发中以面对各种复杂的界面,其实你非要用Row和Column去做已经可以解决大部分的布局问题,但是会涉及到多层的嵌套,我们通常更希望自己的界面扁平化一点。所以就扯出了compose里面的constraintlayout,这个东西对于大家来说已经很熟悉了,xml中用的也不少了,他功能的强大也是有目共睹。但是他在compose里面是怎么使用的呢?让我们跟着官方文档慢慢了解并使用它。
1、什么是constraintlayout
约束布局,一种非常好用的布局,写xml布局用过的都知道,这是一种能让组件想去哪就去哪的布局。
2、constraintlayout有什么作用
image.png这是官方的解释,简单点就是防止嵌套层次过多,使视图设计更加扁平化。xml时防止使用线性布局嵌套过多,compose防止使用Row和Column嵌套过多。
3、constraintlayou在compose中的使用
image.png如下:
implementation "androidx.constraintlayout:constraintlayout-compose:1.0.0-beta02"
image.png
这两个注意官方向我们传达的意思是,compose可以很好地处理嵌套视图过多的问题,在compose中融入constraintlayout只是为了让大家使用方便,也是为了我们方便理解和维护代码。
下面就是介绍它的具体使用方法了,先看文档:
image.png
结合它给出的例子:
@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)
}
) {
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)
})
}
}
可以将使用方法总结为一下几步:
1.添加依赖
implementation "androidx.constraintlayout:constraintlayout-compose:1.0.0-beta02"
2.创建引用
val (button, text) = createRefs()
类似于xml的id,这里是创建了两个组件,一个叫button,一个叫text。
3.创建相应的组件绑定到引用
modifier = Modifier.constrainAs(button)
4.在constrainAs内部实现约束条件。
top.linkTo(parent.top, margin = 16.dp)
这句的意思是该组件位置的顶部与父布局的顶部对齐,距离16dp,这里的parent通常指constraintlayout。
4、实际使用
下面我们来按照这几步自己写一个简单的页面。
比如我们要实现这样一个界面:
image.png
第一步添加依赖就不说了;
第二步创建引用:
我们先分析一下布局,该布局中有三个组件,一个头像Imageview,一个人物名称Textview,还有一个主要成就TextView,总的就是一个imageView和两个TextView三个引用,所以创建三个引用即可:
val (imageref, nameref, descref) = createRefs()
第三步:创建组件绑定引用
Image(
painter = painterResource(id = R.drawable.luxun),
contentDescription = "dog avatar",
modifier = Modifier
.constrainAs(imageref) {
}
)
Text(text = "人物名称:鲁迅",
modifier = Modifier
.constrainAs(nameref) {
}
)
Text(
text = "主要成就:鲁迅作品题材广泛,形式多样灵活,风格鲜明独特,语言幽默。 鲁迅的作品主要以小说、杂文为主,代表作有:小说集《呐喊》《彷徨》《故事新编》等 ;散文集《朝花夕拾》;散文诗集《野草》;杂文集《坟》《热风》《华盖集》《华盖集续编》《南腔北调集》《三闲集》《二心集》《而已集》《且介亭杂文》等。 ",
modifier = Modifier
.constrainAs(descref) {
},
)
如上图所示,创建了三个组件使用constrainAs()分别去绑定三个引用
第四步:在constrainAs内部实现约束条件,在上述代码中加入约束条件。
Image(
painter = painterResource(id = R.drawable.luxun),
contentDescription = "dog avatar",
modifier = Modifier
.constrainAs(imageref) {
top.linkTo(parent.top)
start.linkTo(parent.start)
}
)
Text(text = "人物名称:鲁迅",
modifier = Modifier
.constrainAs(nameref) {
top.linkTo(imageref.top, 3.dp)
start.linkTo(imageref.end, 12.dp)
}
)
Text(
text = "主要成就:鲁迅作品题材广泛,形式多样灵活,风格鲜明独特,语言幽默。 鲁迅的作品主要以小说、杂文为主,代表作有:小说集《呐喊》《彷徨》《故事新编》等 ;散文集《朝花夕拾》;散文诗集《野草》;杂文集《坟》《热风》《华盖集》《华盖集续编》《南腔北调集》《三闲集》《二心集》《而已集》《且介亭杂文》等。 ",
modifier = Modifier
.constrainAs(descref) {
top.linkTo(nameref.bottom, 3.dp)
start.linkTo(imageref.end, 12.dp)
end.linkTo(parent.end,12.dp)
width= Dimension.fillToConstraints
}
)
最后加入组件的一些美化调整,正题代码如下:
package com.example.composedemo2
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.constraintlayout.compose.ConstraintLayout
import androidx.constraintlayout.compose.Dimension
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
DefaultPreview()
}
}
}
@Composable
fun learnConstrainLayout() {
ConstraintLayout {
val (imageref, nameref, descref) = createRefs()
Image(
painter = painterResource(id = R.drawable.luxun),
contentDescription = "dog avatar",
modifier = Modifier
.constrainAs(imageref) {
top.linkTo(parent.top)
start.linkTo(parent.start)
}
.size(100.dp)
.clip(shape = CircleShape),
contentScale = ContentScale.Crop
)
Text(text = "人物名称:鲁迅",
modifier = Modifier
.constrainAs(nameref) {
top.linkTo(imageref.top, 3.dp)
start.linkTo(imageref.end, 12.dp)
}
.fillMaxWidth(),
fontSize = 18.sp,
maxLines = 1,
overflow = TextOverflow.Ellipsis,
textAlign = TextAlign.Left
)
Text(
text = "主要成就:鲁迅作品题材广泛,形式多样灵活,风格鲜明独特,语言幽默。 鲁迅的作品主要以小说、杂文为主,代表作有:小说集《呐喊》《彷徨》《故事新编》等 ;散文集《朝花夕拾》;散文诗集《野草》;杂文集《坟》《热风》《华盖集》《华盖集续编》《南腔北调集》《三闲集》《二心集》《而已集》《且介亭杂文》等。 ",
modifier = Modifier
.constrainAs(descref) {
top.linkTo(nameref.bottom, 3.dp)
start.linkTo(imageref.end, 12.dp)
end.linkTo(parent.end,12.dp)
width= Dimension.fillToConstraints
},
fontSize = 18.sp,
overflow = TextOverflow.Ellipsis
)
}
}
@Preview(showBackground = true)
@Composable
fun DefaultPreview() {
learnConstrainLayout()
}
以上就是我简单mark的constraintlayout的使用了,主要记录一下方便自己使用,如有描述不准确的地方请留言。
网友评论