首页 > 其他分享 >Jetpack Compose学习(14)——ConstraintLayout约束布局使用

Jetpack Compose学习(14)——ConstraintLayout约束布局使用

时间:2024-12-05 17:55:16浏览次数:11  
标签:modifier Compose 14 val Jetpack top ConstraintLayout Modifier linkTo

原文地址: Jetpack Compose学习(14)——ConstraintLayout约束布局使用-Stars-One的杂货小窝

本文阅读之前,需要了解ConstraintLayout的使用!

各位可查阅我的ConstraintLayout使用一文

本系列以往文章请查看此分类链接Jetpack compose学习

引入依赖

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

可在下方链接查看官方的最新版本

Constraintlayout | Jetpack | Android Developers

简单示例

在compose里的约束布局,需要先通过createRef()方法创建ref对象,之后通过Modifier.constrainAs()来进行对应的约束对齐,如下简单例子:

2个组件,图片和文本,文本与图片的top和bottom对齐,位于图片的右侧,间距16dp

注意: createRef(),createRefs(),Modifier.constrainAs()这个ConstraintLayoutScope作用域才能使用!下面的其他的方法也是如此,之后不再赘述!

ConstraintLayout(modifier= Modifier
	.fillMaxWidth()
	.height(100.dp)
	.background(Color.Blue)) {//这里是ConstraintLayoutScope作用域
	
	//createRef
	//val portraitImageRef = remember {
	//    createRef()
	//}
	//val userNameTextRef = remember {
	//    createRef()
	//}

	//这个可以快速创建多个引用(但一次最多只能支持16个变量!)
	val (portraitImageRef,userNameTextRef) = remember{ createRefs()}

	Image(painter = painterResource(id = R.drawable.ic_auto), contentDescription =null ,modifier=Modifier.size(50.dp).constrainAs(portraitImageRef){
		top.linkTo(parent.top)
		start.linkTo(parent.start)
		bottom.linkTo(parent.bottom)
	})

	Text("myname",modifier=Modifier.constrainAs(userNameTextRef){
		top.linkTo(portraitImageRef.top)
		//还可以设置margin和goneMargin,这里我只设置了margin属性
		start.linkTo(portraitImageRef.end, margin = 16.dp)
		bottom.linkTo(portraitImageRef.bottom)
	})

}

constrainAs的函数体中,我们还可以设置当前组件的width和height属性,具体有下面几个选项

Dimension Type Description
wrapContent() 实际尺寸为根据内容自适应的尺寸
matchParent() 实际尺寸为铺满整父组件的尺寸
fillToConstraints() 实际尺寸为根据约束信息拉伸后的尺寸
preferredWrapContent() 如果剩余空间大于根据内容自适应的尺寸时,实际尺寸为自适应的尺寸。如果剩余空间小于内容自适应的尺寸时,实际尺寸则为剩余空间的尺寸。
ratio (String) 根据字符串计算实际尺寸所占比率,例如 "1:2"
percent (Float) 根据浮点数计算实际尺寸所占比率
value (Dp) 将尺寸设置为固定值
preferredValue (Dp) 如果剩余空间大于固定值时,实际尺寸为固定值。如果剩余空间小于固定值时,实际尺寸则为剩余空间的尺寸。

一个简单示例(某个组件占满剩余宽度):

ConstraintLayout(modifier= Modifier
	.fillMaxWidth()
	.height(100.dp)
	.background(Color.Blue)) {
	

	val (tv1Ref,tv2Ref) = remember{ createRefs()}

	Text("一个字",modifier=Modifier.constrainAs(tv1Ref){
		top.linkTo(parent.top)
		start.linkTo(parent.start)
	})
	

	Text("右侧文本内容",modifier=Modifier.constrainAs(tv2Ref){
		start.linkTo(tv1Ref.end)
		end.linkTo(parent.end)
		//占满剩余空间,实际等同于普通约束布局中,给width属性设置为0dp
		width = Dimension.fillToConstraints
	}.background(Color.Yellow))
}

除了上面几个start.linkTo,还有基线的对齐

baseline.linkTo(parent.baseline)

动态更改约束条件

除了上面说到的createRef方法,我们还可以通过Modifier.layoutId(id)createRefFor(id)来联用进行创建ref对象

ConstraintSet对象就表明了当前的布局里的各组件的对齐关系,我们只需要构造ConstraintLayout的时候,传递此对象即可达到动态更新约束条件的效果!

下面是一个简单的示例:

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

@Composable
fun SettingPage(modifier: Modifier = Modifier) {
    val constraints = decoupledConstraints(margin = 32.dp)

    ConstraintLayout(constraints) {
        Button(
            onClick = { /* Do something */ }, modifier = Modifier.layoutId("button")
        ) {
            Text("Button")
        }

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

Barrier

平时在约束布局,不是很常用这个,一般用的GuideLine多些,不过也是记录下

这个需要依托存在的组件才能创建

ConstraintLayout{
	val (tv1Ref,tv2Ref,iv1Ref) = remember{ createRefs()}
	//创建位于组件右边的一个屏障
	val barrier = createEndBarrier(tv1Ref,tv2Ref)
	
	Text("一个字",modifier=Modifier.constrainAs(tv1Ref){
		top.linkTo(parent.top)
		start.linkTo(parent.start)
	})
	
	Text("十四个字",modifier=Modifier.constrainAs(tv2Ref){
		top.linkTo(tv1Ref.bottom)
		start.linkTo(tv1Ref.start)
	})
	
	//image始终位于2个文本的最右边(以最长文本为准)
	Image(painter = painterResource(id = R.drawable.ic_auto), contentDescription =null,modifier=Modifier.size(50.dp).constrainAs(iv1Ref){
		start.linkTo(barrier)
	} )
}

createEndBarrier方法即在组件的右边位置创建屏障,除此之外还有其他3个方向的

  • createStartBarrier()
  • createTopBarrier()
  • createBottomBarrier()

GuideLine

引导线可以通过createGuidelineFromTop()方法直接创建,个人一般用此来进行百分比宽度等划分,然后让组件占满

于上面一样,还有其他方向,这里就不补充了,就是换个名字,代码提示直接可以搜到了

方法可接受一个0-1f范围之间的百分比或者固定的偏移量dp,如下面例子:

val guide = createGuidelineFromTop(0.2f)
val guide = createGuidelineFromTop(20.dp)

一个完整使用示例:

ConstraintLayout(modifier= Modifier
        .fillMaxSize()
        .background(Color.Blue)) {

        val (tv2Ref) = remember { createRefs() }
        
        val guide = createGuidelineFromTop(0.2f)

        Text("底下占满",modifier= Modifier
            .constrainAs(tv2Ref) {
                top.linkTo(guide)
                bottom.linkTo(parent.bottom)
                width = Dimension.matchParent
                height = Dimension.fillToConstraints
            }
            .background(Color.Yellow))
    }

Chain

熟悉约束布局使用都知道这个了,有水平或垂直2种,然后ChainStyle类型有3种,这里不赘述了

  • createVerticalChain()
  • createHorizontalChain()
createVerticalChain(imageOneRef, imageTwoRef, chainStyle = ChainStyle.Spread)

参考

标签:modifier,Compose,14,val,Jetpack,top,ConstraintLayout,Modifier,linkTo
From: https://www.cnblogs.com/stars-one/p/18589073

相关文章

  • P9142 [THUPC 2023 初赛] 欺诈游戏 题解
    P9142[THUPC2023初赛]欺诈游戏题面这个游戏名叫《走私游戏》。游戏规则大概是这样的:一名玩家扮演走私者,一名玩家扮演检察官。走私者可以将\(x\)日元(\(x\)为\([0,n]\)内的整数,由走私者决定)秘密放入箱子中,而检查官需要猜测箱子中的金额。假设检察官猜了\(y\)(\(y\)也必......
  • docker-compose yaml version
    在DockerCompose文件中,version字段是必需的,它告诉DockerCompose工具使用哪个版本的YAML文件格式来解析Compose文件。目前,DockerCompose支持的版本有1, 2, 2.x, 3, 3.x等。其中,3及以上版本支持更多的特性,比如多服务网络 FROMopenjdk:8-jreRUNmkdir/app#复制jar......
  • 142页CIO工作指导手册CIO的两大职责及应统管的7大领域大揭秘
    解读资料来源于网络,如有侵权可联络删除。        CIO工作指导手册,主要涵盖IT管理、投资成本管理、组织人才管理、资源组织战略、IT服务管理、风险管理、IT架构、企业创新等多个方面,为CIO在企业中的工作提供全面指导,助力企业实现高效的信息化建设与管理。1.IT管理......
  • C#知识点14
    四层网络协议:应用层传输层网络层网络接口层四层网络模型每层各司其职,消息在进入每一层时都会多加一个报头,每多一个报头可以理解为数据报多戴一顶帽子为什么要将数据切片软件琛琛是属于应用层上的而"李东","亚健康终结者"这两条消息在进入传输层时使用的是传输层上的TCP......
  • 复习题-W14-1级和2级
    C01.L13.结业测试.测试题2.山峰数(DLOI2018t1)题目描述给出一个五位数的正整数,不妨假设这个整数的万位数字是a,千位数字是b,百位数字是c,十位数字是d,个位数字是e。如果满足:a<b<c且c>d>e,那么这个五位数就是山峰数。输入格式一个五位数。输出格式如......
  • 洛谷题单指南-线段树-P1471 方差
    原题链接:https://www.luogu.com.cn/problem/P1471题意解读:给定序列a[n],支持三种操作:1.将区间每个数加上一个数2.查询区间的平均数3、查询区间的方差解题思路:要支持区间修改和查询,首选线段树,下面看线段树节点需要维护的信息平均数=区间和/n,所以第一个要维护的信息是区间和......
  • 力扣 LeetCode 51. N皇后(Day14:回溯算法)
    解题思路:每次进入backtracking都表示进入下一行每个backtracking中处理当前行的各个列,看各列是否合法isValid中因为是一行一行向下遍历的,所以对应的当前行一定满足条件,没有放置过其他皇后,只需要看对应的列是否满足即可是否符合需要看左上45°和右上45°,之所以是往上看,......
  • 学习Python的笔记14--迭代器和生成器
    1.迭代器(Iterator)概念:迭代意味着重复多次,就像循环一样。迭代器是一个可以记住遍历的位置的对象。迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。1.iter():返回迭代器自身。2.next():返回容器的下一个元素,如果没有元素了,抛St......
  • Python基础学习-14面向对象与类
    目录1、面向对象2、类3、基本语法和规范4、类的继承5、本节总结1、面向对象•对象:Object我们将生活中的业务场景抽象为对象类是对一类事物描述,是抽象的、概念上的定义:比如“人”对象是实际存在的该类事物的每个个体,因而也称实例(instance)。比如“张三”2、类......
  • Compose组件之Box
    在JetpackCompose中,Box是一个非常常用的布局组件,它可以将子组件层叠起来,类似于一个容器。通过Box,我们可以轻松地进行元素的定位、堆叠等操作。今天,我们就来详细了解一下Box的用法,以及如何通过Box来实现一些常见的UI效果。1.Box的基础用法Box是一个非常灵活的布局容器,它......