欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

ConstraintLayout的使用

程序员文章站 2022-04-25 10:43:27
...

ConstraintLayout的使用

这篇文章主要根据官方文档的结构,加上自己的理解来介绍它的用法。
ConstraintLayout 翻译过来是约束布局,可以对子view添加各种约束条件达到某种目的,非常灵活。
ConstraintLayout是一个ViewGroup的导出类,可以用灵活的方式来放置部件和确定部件大小。

引入依赖

开始使用ConstraintLayout前,需要在工程引入ConstraintLayout依赖库。
添加以下依赖到你的build.gradle 文件中:

dependencies {
    implementation 'com.android.support.constraint:constraint-layout:1.1.0'
}

开发指南

主要通过以下几个方面来介绍ConstraintLayout的使用和特性:

  • 相对定位
  • 边距
  • 居中和偏移
  • 圆形定位
  • 可见度的行为
  • 部件尺寸的约束
  • 比例
  • 链条

相对定位

相对定位跟RelativeLayout非常像,一个部件相对另外一个部件的位置。如把ButtonB放到ButtonA的右边,可以这样写:

<Button android:id="@+id/buttonA" ... />
<Button android:id="@+id/buttonB" ...
    app:layout_constraintLeft_toRightOf="@+id/buttonA" />

ConstraintLayout的使用

有以下可用的约束属性:

  • layout_constraintLeft_toLeftOf
  • layout_constraintLeft_toRightOf
  • layout_constraintRight_toLeftOf
  • layout_constraintRight_toRightOf
  • layout_constraintTop_toTopOf
  • layout_constraintTop_toBottomOf
  • layout_constraintBottom_toTopOf
  • layout_constraintBottom_toBottomOf
  • layout_constraintBaseline_toBaselineOf
  • layout_constraintStart_toEndOf
  • layout_constraintStart_toStartOf
  • layout_constraintEnd_toStartOf
  • layout_constraintEnd_toEndOf

ConstraintLayout的使用

这些属性都是可以引用另外一个部件的id,或者parent(指的是引用父容器,实际指的是ConstraintLayout)

外边距

ConstraintLayout的使用

如果设置了margins,它会运用于相应的约束(如果存在的话),强制将margins当做一个空间在目标的边和原始的边之间,有以下有效的属性:

  • android:layout_marginStart
  • android:layout_marginEnd
  • android:layout_marginLeft
  • android:layout_marginTop
  • android:layout_marginRight
  • android:layout_marginBottom

注意这些属性的值只能是正数或者0

当连接了GONE的部件时的边距

如果约束目标的部件为GONE时,可以设置以下属性来设置边距,只在目标GONE时有效.

  • layout_goneMarginStart
  • layout_goneMarginEnd
  • layout_goneMarginLeft
  • layout_goneMarginTop
  • layout_goneMarginRight
  • layout_goneMarginBottom

注意目标为GONE时同时设置了layout_goneMarginStart和layout_marginStart,只有layout_goneMarginStart会有效

居中和偏移

看个例子

<android.support.constraint.ConstraintLayout ...>
             <Button android:id="@+id/button" ...
                 app:layout_constraintLeft_toLeftOf="parent"
                 app:layout_constraintRight_toRightOf="parent/>
         </>

ConstraintLayout的使用

这个例子控件添加了左边跟父容器对齐,右边也跟父容器对齐的约束。看是不可能发生,除非子控件的宽跟父容器一致。
实际上如果这样这种对立面的约束(横向或者竖向)会导致部件刚好居中,可以想象成两个相反方向的力度拉伸,力是相等的,可以类比拔河,双方的力一样,刚好居中。

偏移

对立面的约束默认是居中,可以通过设置以下两个属性进行偏向一边
* layout_constraintHorizontal_bias
* layout_constraintVertical_bias

ConstraintLayout的使用

值为0到1,如果是0.5,部件刚好居中
使用偏移,可以放置部件到自己想要的位置

例如把一个按钮放到水平的30%的位置,默认是50%。

<android.support.constraint.ConstraintLayout ...>
    <Button android:id="@+id/button" ...
     app:layout_constraintHorizontal_bias="0.3"
     app:layout_constraintLeft_toLeftOf="parent"
     app:layout_constraintRight_toRightOf="parent/>
    </>

圆形定位(1.1新增)

你可以通过一个部件的中心约束另外一个部件的中心,通过角度,距离。这使得你定位部件在一个圆上。对应的属性有:

  • layout_constraintCircle : 引用另外一个部件的id
  • layout_constraintCircleRadius : 到另一个部件中心点的距离,实际就是半径
  • layout_constraintCircleAngle : 角度 (0 to 360)

ConstraintLayout的使用
ConstraintLayout的使用

例如: ButtonB 位于 ButtonA中心点的45度,中心点距离为100dp

<Button android:id="@+id/buttonA" ... />
  <Button android:id="@+id/buttonB" ...
      app:layout_constraintCircle="@+id/buttonA"
      app:layout_constraintCircleRadius="100dp"
      app:layout_constraintCircleAngle="45" />

可见度的行为

ConstraintLayout有特殊处理被标记为GONE的部件(layout_goneMargin).
GONE的部件,通常不显示和不是layout一部分(实际上他们的dimension不改变当标记为GONE时 )
但是根据layout的计算,GONE仍然是它的一部分,有重大的区别:
对于布局的传递,他们的dimension认为是0(基本上他们可以当做一个点来看待)
如果他们约束了其他部件,它的所有margins当做为0
这种行为允许构建你能暂时标记GONE的部件的布局,而不是破坏布局。当做一些简单的动画时特别有用

ConstraintLayout的使用

尺寸的约束

  • android:minWidth 设置最小的宽度
  • android:minHeight 设置最小的高度
  • android:maxWidth 设置最大的宽度
  • android:maxHeight 设置最大的高度

这些值用在ConstraintLayout,当他们的dimensions设置成WRAP_CONTENT的时候

部件尺寸的约束

部件的尺寸是通过设置android:layout_widthandroid:layout_height属性指定的,有3种方式:
* 使用一个明确的尺寸值(字面值如123dp或者值引用)
* 使用WRAP_CONTENT,请求部件计算自己的值
* 使用0dp,等价于MATCH_CONSTRAINT,类似于其他layout的match_parent,在约束条件下可以用的最大的值

ConstraintLayout的使用70)

前两种跟其他的布局类似。最后一种会重新计算部件通过适配设置的约束。如果边距有设置,计算时也会考虑边距。

重要提醒:ConstraintLayout不推荐包含MATCH_PARENT的部件。类似行为可以使用MATCH_CONSTRAINT 这种方式,把相应的左/右,上/下约束设置成“parent”即可。

WRAP_CONTENT: 强制约束(1.1新增)

如果一个尺寸设置了WRAP_CONTENT,在1.1版本之前,他们会当做字面量来处理,意味着约束将没有限制结果的尺寸。通常这已经足够(处理更快点),但是一些情况下,你可以想要使用WRAP_CONTENT,仍然保持强制的约束限制结果的大小,这种情况下添加以下相应的属性:

  • app:layout_constrainedWidth=”true|false”
  • app:layout_constrainedHeight=”true|false”

MATCH_CONSTRAINT 尺寸(1.1新增)

当一个尺寸设置为MATCH_CONSTRAINT,默认行为的结果大小为是用所有可用的空间,有以下几个额外修改的属性:

  • layout_constraintWidth_min and layout_constraintHeight_min : 设置最小的大小
  • layout_constraintWidth_max and layout_constraintHeight_max : 设置最大的大小
    layout_constraintWidth_percent and layout_constraintHeight_percent : 设置大小根据百分比

值可以是dp的字面值或者wrap,如果是wrap表示跟WRAP_CONTENT一样

百分比大小

使用百分比,需要设置下列事物:
* 尺寸需要设置成MATCH_CONSTRAINT (0dp)
* 这两个属性要设置成percent app:layout_constraintWidth_default=”percent” or app:layout_constraintHeight_default=”percent” (1.1之后不需要)
* 设置layout_constraintWidth_percent 或者 layout_constraintHeight_percent属性的值为0到1

比例

你可以声明一个部件尺寸的宽高比例,为了做到那样,你需要最少设置一个约束尺寸为0dp(也就是MATCH_CONSTRAINT),然后设置layout_constraintDimensionRatio 的比例值。例如:

 <Button android:layout_width="wrap_content"
        android:layout_height="0dp"
        app:layout_constraintDimensionRatio="1:1" /> 

这个例子将设置高和宽一样
比例可以这样表达:
* 一个浮点数,代表宽高之间的比例
* 比例的格式”width:height”

也可以同时把宽度尺寸设置为MATCH_CONSTRAINT (0dp),这样情况系统设置最大的尺寸来满足所有的约束和保持这个比例。可以约束一一条指定的边基于另外一条边的大小。你可以在前面加上W,或者H。来分别约束宽或者高,例如:

 <Button android:layout_width="0dp"
    android:layout_height="0dp"
    app:layout_constraintDimensionRatio="H,16:9"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintTop_toTopOf="parent"/>

设置基于高度大小满足(16:9)的宽.

链条

链条提供一组行为在一条单轴上(横向或者竖向),其他轴可以有独立的约束。

ConstraintLayout的使用

创建一个链条

如果通过双向连接将一组小部件连接到一起,就会被认为是一个链条。

ConstraintLayout的使用

链头

链条由链的第一个元素上的属性控制,链头是水平链的最左边的部件,也是垂直链的最顶层的部件。

边距

如果在连接上指定了页边距,就会考虑到它们。在扩展链的情况下,将从分配的空间中扣除

链条样式

当在链的第一个元素上设置属性layout_constraintHorizontal_chainStyle 或者 layout_constraintVertical_chainStyle时,链条的行为将根据指定的样式进行更改(默认是CHAIN_SPREAD)。

  • CHAIN_SPREAD – 这些元素将会分散开来,相同间距 (default style)
    Weighted chain – 在 CHAIN_SPREAD 模式下, 如果一些部件设置成 MATCH_CONSTRAINT, 他们将分配剩余空间(类似layout_weight)
    CHAIN_SPREAD_INSIDE – 类似,但是链的端点不会分散开来
    CHAIN_PACKED – 链条的组成部分将被打包在一起。然后,孩子的水平或垂直偏差属性会影响填充元素的位置

ConstraintLayout的使用

Weighted chains

链的默认行为是在可用空间中均匀地分布元素。如果一个或多个元素使用MATCH_CONSTRAINT,它们将使用可用的空闲空间(在它们之间平均分配)。属性layout_constraintHorizontal_weight 和 layout_constraintVertical_weight束的属性将控制如何使用匹配约束来在元素之间分配空间。例如,在一个包含两个元素的链上,使用匹配约束,第一个元素使用2的权重,第二个元素的权重为1,第一个元素占用的空间将是第二个元素的两倍

边距和链条 (在1.1)

当在链条上使用margins时,margins是附加的。
例如,在水平链上,如果一个元素定义了10dp的右边距,而下一个元素定义了5dp的左边距,那么这两个元素之间的边距是15 dp。
当计算链用来定位物品的剩余空间时,一个物品加上它的边缘被考虑在一起。剩余的空间不包含边距。

虚拟辅助对象

除了前面详细介绍的内在功能之外,你还可以在约束布局中使用特殊的助手对象来帮助您进行布局。目前,Guideline 允许您创建相对于约束布局容器的水平和垂直的指导方针。然后,可以通过将小部件限制在这些指导方针中来定位。在1.1中,也加入了Barrier(障碍)和Group(组)。

Guideline

工具类表示约束布局的指导助手对象。辅助对象不会显示在设备上。他们仅仅使用在约束布局内部。

Guideline分为 横向和竖向:
* 竖向是宽为0,高是父的约束布局的高
* 横向是高为0,宽是父的约束布局的宽

用3种方式定位一个Guideline
* 在布局中指定左或者顶部的距离(layout_constraintGuide_begin)
* 在布局中指定右边左或者底部的距离 (layout_constraintGuide_end)
* 在布局中指定一个宽高的百分比 (layout_constraintGuide_percent)

部件可以被Guideline约束,允许多个部件可以很容易地从一个Guideline中定位,或者允许使用百分比定位来进行响应式布局行为。

Barrier(界线)

一个Barrier可以引入多个部件作为输入,然后建立一条虚拟引导线,这条线基于基于最大部件在一条指定的边上。例如一条左边界线对齐所有的views

     <android.support.constraint.Barrier
              android:id="@+id/barrier"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              app:barrierDirection="start"
              app:constraint_referenced_ids="button1,button2" />

Group(组)

这个类控制一组引用部件的可见度。部件引用添加通过逗号分开。例如:

     <android.support.constraint.Group
              android:id="@+id/group"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:visibility="visible"
              app:constraint_referenced_ids="button4,button9" />

该组的可见性将应用于所引用的部件。这是一种方便的方法,可以轻松地隐藏/显示一组小部件,而无需以编程方式维护该集合。

Multiple groups

多个群组可以引用相同的小部件——在这种情况下,XML声明顺序将定义最终可见性状态(最后声明的组将拥有最后一个单词)

优化器(1.1版)

在1.1的版暴露了约束优化器,你可以通过添加标签app:layout_optimizationLevel指定哪些优化,用来应用到ConstraintLayout元素中:

  • standard: 只对direct和barrier约束进行优化
  • direct: 优化直接的约束
  • barrier:优化barrier的约束
  • chain:优化链条的约束 (实验性的)
  • dimensions:优化尺寸的测量(实验性的),减少匹配约束元素的测量的次数。
    这个属性是一个掩码,所以您可以决定打开或关闭特定的优化,列出你想要的,例如
app:layout_optimizationLevel="direct|barrier|chain"
相关标签: 布局