ConstrainLayout为束缚布局,它并不是Compose独有的一种布局类型,在xml中咱们应该也有所触摸,而且现在xml的模板便是束缚布局,它能够经过多种束缚(constrain)来组合布局种其它组件,一般用来代替布局种多个columnrow或许box等,能够简化布局的复杂性。

在Compose运用束缚布局,需求提前增加一下依靠:

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

目前最新版别为:1.1.0-alpha11,安稳版别还停留在:1.0.1

此篇文章将从根底、GuideLine、Barrier和Chain四个方面介绍束缚布局

Jetpack Compose - 约束布局​ConstrainLayout

根底

在刚触摸束缚布局时,咱们用一个最简单的示例来学习下如何在Compose种运用束缚布局,下面咱们运用束缚布局创立一个坐落屏幕正中间的文本组件

Jetpack Compose - 约束布局​ConstrainLayout

在上面代码中,咱们先经过createRef()创立了一个束缚布局的引证,然后经过Modifier.constrainAs(text){}将创立的引证和Text相关起来,最终在constrainAs第二个参数Lambda中增加束缚条件,使它上下左右都和父布局相关,这样它就会显示在屏幕的正中间。

作用如下图所示

Jetpack Compose - 约束布局​ConstrainLayout

需求注意的是createRef()Modifier.constrainAs()只能够作用于束缚布局下面,非束缚布局是不能够创立引证和相关引证的

  • Modifier.constrainAs(){}的Lambda中除了能够用linkTo设置束缚条件外,还能够设置宽、高、visibility是否可见、透明度等信息;
  • linkTo()还能够设置可见margin和不可见margin,都是十分实用的功能。

上面咱们只提到了子组件和父组件的相关办法,那么子组件和子组件之间的相关该如何处理呢,接下来看看这种场景

咱们在上面的代码中再增加一个按钮组件,使它坐落文本正下方

Jetpack Compose - 约束布局​ConstrainLayout

这里咱们创立引证的办法由createRef()变成了createRefs(),此办法能够创立多个引证,选用的是解构的写法,可是要注意的是最多只能创立16个引证,千万别超出这个数量束缚

然后在TextButton的相关办法中将自身的top链接到textbottom,这样就达到了按钮在文本下方的作用。

Jetpack Compose - 约束布局​ConstrainLayout
  • createRefcreateRefs是为束缚布局中可组合项创立引证的办法
  • constrainAs是相关创立的引证,而且它的Lambda中能够指定其束缚条件
  • 束缚条件中parent是一个现成的引证,指向的是束缚布局本身,子组件可指定其束缚布局创立束缚条件。

GuideLine引导线

经过根底部分咱们了解到在束缚布局中能够指定组件进行束缚条件,此刻有个需求,屏幕中有两个文本,他们是处于屏幕的正中间,这样就能够选用GuideLine来完成此需求了,它是一种辅助性工具,并不会创立实践的可组合项,下面看代码如何完成

Jetpack Compose - 约束布局​ConstrainLayout

上面代码中咱们经过createGuidelineFromTop(0.5F)创立了一个水平的引导线,而且它间隔屏幕顶部50%的间隔,也便是屏幕笔直方向居中的方位,然后将第一个Text的下方束缚条件链接到引导线的方位,将第二个Text的上方束缚条件链接到引导线的方位,这样两个文本的方位就别离坐落引导线上方和下方,也就达到了他俩坐落屏幕中心的作用。

Jetpack Compose - 约束布局​ConstrainLayout

引导线一共分为水平笔直两个方向,而且能够按份额来创立,也能够按照详细间隔值创立引导线

Jetpack Compose - 约束布局​ConstrainLayout

这里我只列出五种办法创立水平或许笔直方向的引导线,其中第二种办法以详细间隔办法创立引导线适用于所有的办法。引导线能够协助咱们处理开发中很多对齐的问题,大家能够选用感受下。

Barrier屏障线

屏障线和引导线相同,它也是一种辅助性的工具,也不会创立实践的可组合项,在解释屏障线的作用之前,咱们先看一个界面

Jetpack Compose - 约束布局​ConstrainLayout

界面中有三个文本,上方、下方和右边,这时候需求完成的作用最右边的文本是坐落上方和下方文本的右边,而且不能够重叠,上方和下方的文本谁的长度更长,右边的文本就要对齐最长的那个。

假如不选用束缚布局的情况下,或许需求在上方和下方文本外层再包一个Column组件,然后让右边的文本对齐Column的右侧

可是束缚布局中的屏障线能够完美的处理此问题,而且不需求增加额外的组件。咱们在编码之前先思考一下计划:

  • 首要经过屏障线将上下文本包裹起来,然后在其右侧增加一个引导线
  • 然后将左边本文的start束缚条件对齐屏障线,这样此文本组件就会对齐上下文本最长的那个了

好了,思路有了就直接编码试试看

Jetpack Compose - 约束布局​ConstrainLayout

经过createEndBarrier(topTv,bottomTv)就能够在上下文本的右侧创立一个屏蔽线了,这样在束缚条件中能够轻松的设置对齐束缚,十分简易的协助咱们完成了上述需求,在不需求创立额外可组合项的条件下。

除了createEndBarrier()以外,Compose的束缚布局还提供了createTopBarrier()createBottomBarrier()createStartBarrier()三中办法创立屏蔽线。

Chain链

束缚布局中的Chain链能够协助咱们完成线性布局中等分的功能,有点相似于权重的概念(可是和权重仍是有所区别),而且还能够完成除可组合项外剩下空间的权重,或许解释有点晦涩难懂,下面经过实践代码来看看它带来的作用,咱们先经过Chain来完成文本等分的作用

Jetpack Compose - 约束布局​ConstrainLayout

布局中一共有三个文本,它们整个水平方向均匀分布,首要经过createHorizontalChain()创立了一个水平方向的链,将三个文本与其相关,这样咱们就不需求在文本的束缚条件中再设置水平方向的束缚条件,链会主动依据ChainStyle协助咱们布局。

createHorizontalChain()第二个参数为chainStyle,一共有三大种(有一种可自定义),这里咱们先选用默许的Spread办法,先来看看完成的作用

Jetpack Compose - 约束布局​ConstrainLayout

在作用图中,将除文本以外的空间用红框标示起来,能够看出四个红框的宽度是等宽的,然后三个文本别离位居于四个红框中间,这样三个文本在水平方向上便是均匀分布了。

然后咱们将createHorizontalChain第二个参数换成ChainStyle.SpreadInside办法,再来看看作用

Jetpack Compose - 约束布局​ConstrainLayout

SpreadInside办法的作用便是将可组合项最左边和最右边的空间给去除掉了,然后中间剩下的空间变大,可组合项的方位也随之改动。

最终再看看ChainStyle.Packed办法,此办法有个参数bias表明误差,默以为0.5f,咱们先看看默许的误差作用

Jetpack Compose - 约束布局​ConstrainLayout

Packed(0.5F)办法和SpreadInside有点相似,它去除的是可组合项中间的空间,然后最左面和最右边的空间等分了,这样咱们三个文本就会挤在水平方向的最中间,假如将bias设置为0.1F会是什么作用呢?

Jetpack Compose - 约束布局​ConstrainLayout

bias的值修改为0.1F之后就会变成上面图片的作用,左边和右边的剩下空间份额就会变成1:9,这种仍是比较容易了解的,在水平方向的屏蔽线,bias会影响左右剩下空间的份额。

屏蔽线除了createHorizontalBarrier()还有createVerticalChain()用于创立笔直方向的屏蔽线,用法和水平屏蔽线一致。

关于ConstrainLayout的知识就介绍这么多啦,后面咱们尝试用束缚布局中MotionLayout完成一个可折叠的标题栏

关于我

我是Taonce,假如觉得本文对你有所协助,帮忙重视、赞或许收藏三连一下,谢谢~