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

ConstraintLayout

程序员文章站 2022-06-08 16:29:18
...

Relative positioning is one of the basic building blocks of creating layouts in ConstraintLayout. Those constraints allow you to position a given widget relative to another one. You can constrain a widget on the horizontal and vertical axis:

相对定位是约束布局中创建布局的基本构件之一。这些约束允许您将给定的小部件相对于另一个小部件定位。你可以在水平轴和垂直轴上约束一个小部件:

  • Horizontal Axis: left, right, start and end sides 水平轴: 左,右,开始和结束边
  • Vertical Axis: top, bottom sides and text baseline 垂直轴: 顶部、底部和文本基线

The general concept is to constrain a given side of a widget to another side of any other widget.

通常的概念是将小部件的给定端约束到任何其他小部件的另一端。

For example, in order to position button B to the right of button A (Fig. 1):

例如,为了使按钮 b 位于按钮 a 的右边(图1) :

ConstraintLayout

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

Fig. 1 - Relative Positioning Example 图1- 相对定位的例子

you would need to do:

你需要做的是:

This tells the system that we want the left side of button B to be constrained to the right side of button A. Such a position constraint means that the system will try to have both sides share the same location.

这告诉系统,我们希望将按钮 b 的左侧限制在按钮 a 的右侧。这样的位置约束意味着系统将设法使双方共享同一位置

ConstraintLayout

<Button android:id="@+id/buttonB" ..
  app:layout_constraintLeft_toLeftOf="parent" />

Fig. 2 - Relative Positioning Constraints 图2- 相对定位约束

Here is the list of available constraints (Fig. 2):

下面是可用约束的列表(图2) :

  • 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

They all take a reference id to another widget, or the parent (which will reference the parent container, i.e. the ConstraintLayout):

它们都接受另一个小部件或父部件的引用 id (这将引用父容器,即 ConstraintLayout) :

ConstraintLayout

<androidx.constraintlayout.widget.ConstraintLayout ...>
             <Button android:id="@+id/button" ...
                 app:layout_constraintLeft_toLeftOf="parent"
                 app:layout_constraintRight_toRightOf="parent/>
         </>

Fig. 3 - Relative Positioning Margins 图3- 相对定位边距

If side margins are set, they will be applied to the corresponding constraints (if they exist) (Fig. 3), enforcing the margin as a space between the target and the source side. The usual layout margin attributes can be used to this effect:

如果设置了边距,它们将应用于相应的约束(如果存在的话)(图3) ,将边距作为目标和源端之间的空间。通常的布局边距属性可以用来实现这个效果:

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

Note that a margin can only be positive or equals to zero, and takes a Dimension.

请注意,边距只能为正或等于零,并且需要一个维度。

When a position constraint target’s visibility is View.GONE, you can also indicate a different margin value to be used using the following attributes:

当一个位置约束目标的可见性被查看时,你也可以使用下面的属性来指示一个不同的边距值:

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

A useful aspect of ConstraintLayout is in how it deals with “impossible” constrains. For example, if we have something like:

Constraint layout 的一个有用方面是它如何处理“不可能的”约束:

Unless the ConstraintLayout happens to have the exact same size as the Button, both constraints cannot be satisfied at the same time (both sides cannot be where we want them to be).

除非 constraint 布局碰巧具有与 Button 完全相同的大小,否则两个约束不能同时满足(两边不能在我们希望的位置)。

ConstraintLayout

Fig. 4 - Centering Positioning 图4- 定心定位

What happens in this case is that the constraints act like opposite forces pulling the widget apart equally (Fig. 4); such that the widget will end up being centered in the parent container. This will apply similarly for vertical constraints.

在这种情况下,约束的作用就像是相反的力同样地将部件拉开(图4) ; 这样部件最终将居中在父容器中。这同样适用于垂直约束。

The default when encountering such opposite constraints is to center the widget; but you can tweak the positioning to favor one side over another using the bias attributes:

当遇到这些相反的约束时,默认的做法是将小部件置于中心位置; 但是你可以使用 bias 属性来调整定位以偏向一边而不是另一边:

  • layout_constraintHorizontal_bias
  • layout_constraintVertical_bias

ConstraintLayout

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

Fig. 5 - Centering Positioning with Bias 图5- 偏心定位

For example the following will make the left side with a 30% bias instead of the default 50%, such that the left side will be shorter, with the widget leaning more toward the left side (Fig. 5):

例如,下面将使左侧偏向30% ,而不是默认的50% ,这样左侧将更短,与小部件更倾向于左侧(图5) :

Using bias, you can craft User Interfaces that will better adapt to screen sizes changes. 使用偏见,您可以工艺用户界面,将更好地适应屏幕尺寸的变化

You can constrain a widget center relative to another widget center, at an angle and a distance. This allows you to position a widget on a circle (see Fig. 6). The following attributes can be used:

您可以将一个小部件中心相对于另一个小部件中心约束为一个角度和一段距离。这允许你在一个圆上放置一个小部件(见图6)。可以使用以下属性:

  • layout_constraintCircle : references another widget id : 引用另一个小部件 id
  • layout_constraintCircleRadius : the distance to the other widget center : 到另一个小部件中心的距离
  • layout_constraintCircleAngle : which angle the widget should be at (in degrees, from 0 to 360) : 小部件应该处于哪个角度(以度为单位,从0到360)

ConstraintLayout

ConstraintLayout

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

Fig. 6 - Circular Positioning 图6- 圆形定位

ConstraintLayout has a specific handling of widgets being marked as View.GONE.

ConstraintLayout 对标记为 View.GONE 的小部件有一个特定的处理。

GONE widgets, as usual, are not going to be displayed and are not part of the layout itself (i.e. their actual dimensions will not be changed if marked as GONE).

GONE 小部件,像往常一样,不会显示,也不是布局本身的一部分(也就是说,如果标记为 GONE,它们的实际尺寸不会改变)。

But in terms of the layout computations, GONE widgets are still part of it, with an important distinction:

但在布局计算方面,GONE widget 仍然是其中的一部分,但有一个重要区别:

  • For the layout pass, their dimension will be considered as zero (basically, they will be resolved to a point) 对于布局通道,它们的维度将被视为零(基本上,它们将被解析为一个点)
  • If they have constraints to other widgets they will still be respected, but any margins will be as if equals to zero 如果他们对其他小部件有约束,他们仍然会受到尊重,但任何利润都将等于零

ConstraintLayout

Fig. 7 - Visibility Behavior 图7- 能见度行为

This specific behavior allows to build layouts where you can temporarily mark widgets as being GONE, without breaking the layout (Fig. 7), which can be particularly useful when doing simple layout animations.

这种特定的行为允许建立布局,你可以暂时标记为部件消失,而不破坏布局(图7) ,这可以是特别有用的时候,做简单的布局动画。

**Note: **The margin used will be the margin that B had defined when connecting to A (see Fig. 7 for an example). In some cases, this might not be the margin you want (e.g. A had a 100dp margin to the side of its container, B only a 16dp to A, marking A as gone, B will have a margin of 16dp to the container). For this reason, you can specify an alternate margin value to be used when the connection is to a widget being marked as gone (see the section above about the gone margin attributes).

注意: 使用的边距将是 b 连接到 a 时定义的边距(例如,见图7)。在某些情况下,这可能不是你想要的保证金。A 的容器侧边距为100dp,b 的容器侧边距为16dp,表示 a 离开了,b 的容器侧边距为16dp)。出于这个原因,您可以指定一个备用的边距值,当连接到一个标记为已消失的小部件时使用(参见上面关于消失的边距属性的部分)。

You can define minimum and maximum sizes for the ConstraintLayout itself:

你可以为 constraint 布局本身定义最小和最大尺寸:

  • android:minWidth set the minimum width for the layout 设置布局的最小宽度
  • android:minHeight set the minimum height for the layout 设置布局的最小高度
  • android:maxWidth set the maximum width for the layout 设置布局的最大宽度
  • android:maxHeight set the maximum height for the layout 设置布局的最大高度

Those minimum and maximum dimensions will be used by 这些最小和最大尺寸将用于ConstraintLayout when its dimensions are set to 当它的尺寸设置为WRAP_CONTENT.

The dimension of the widgets can be specified by setting the android:layout_width and android:layout_height attributes in 3 different ways:

可以通过三种不同的方式设置 android: layout _ width 和 android: layout _ height 属性来指定 widget 的大小:

  • Using a specific dimension (either a literal value such as 使用一个特定的维度(或者一个字面值,如123dp or a 或者Dimension reference) 参考)
  • Using 使用WRAP_CONTENT, which will ask the widget to compute its own size ,这将要求窗口小部件计算自己的大小
  • Using 使用0dp, which is the equivalent of " 这相当于MATCH_CONSTRAINT"

ConstraintLayout

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

ConstraintLayout

Fig. 8 - Dimension Constraints 图8- 尺寸限制

The first two works in a similar fashion as other layouts. The last one will resize the widget in such a way as matching the constraints that are set (see Fig. 8, (a) is wrap_content, (b) is 0dp). If margins are set, they will be taken in account in the computation (Fig. 8, © with 0dp). 前两个版面设计与其他版面设计类似。最后一个将调整小部件的大小,以匹配设置的约束(见图8,(a)是 wrap _ content,(b)是0dp)。如果设置了边距,它们将在计算中被考虑进去(图8,©和0dp)

**Important: **MATCH_PARENT is not recommended for widgets contained in a ConstraintLayout. Similar behavior can be defined by using MATCH_CONSTRAINT with the corresponding left/right or top/bottom constraints being set to "parent".

重要提示: 对于 ConstraintLayout 中包含的小部件,不推荐使用 MATCH _ parent。使用 MATCH _ constraint 可以定义类似的行为,并将相应的左/右或顶/底约束设置为“ parent”。

If a dimension is set to WRAP_CONTENT, in versions before 1.1 they will be treated as a literal dimension – meaning, constraints will not limit the resulting dimension. While in general this is enough (and faster), in some situations, you might want to use WRAP_CONTENT, yet keep enforcing constraints to limit the resulting dimension. In that case, you can add one of the corresponding attribute:

如果维度设置为 WRAP _ content,在1.1之前的版本中,它们将被视为文字维度——意思是,约束不会限制结果维度。一般来说,这已经足够(而且更快)了,但在某些情况下,您可能希望使用 WRAP _ content,同时保持强制约束以限制结果维度。在这种情况下,你可以添加一个相应的属性:

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

When a dimension is set to MATCH_CONSTRAINT, the default behavior is to have the resulting size take all the available space. Several additional modifiers are available:

当维度设置为 MATCH _ constraint 时,默认行为是让结果大小占用所有可用空间。有几个额外的修饰符可用:

  • layout_constraintWidth_min and 及layout_constraintHeight_min : will set the minimum size for this dimension : 将设置此维度的最小大小
  • layout_constraintWidth_max and 及layout_constraintHeight_max : will set the maximum size for this dimension : 将设置此维度的最大大小
  • layout_constraintWidth_percent and 及layout_constraintHeight_percent : will set the size of this dimension as a percentage of the parent : 将此维度的大小设置为父维度的百分比

The value indicated for min and max can be either a dimension in Dp, or “wrap”, which will use the same value as what 为 min 和 max 指示的值可以是 Dp 中的维度,也可以是“ wrap” ,后者将使用与WRAP_CONTENT would do. 可以To use percent, you need to set the following: 要使用% ,需要设置以下内容:

  • The dimension should be set to 尺寸应该设置为MATCH_CONSTRAINT (0dp)
  • The default should be set to percent 默认值应该设置为%app:layout_constraintWidth_default="percent" or 或app:layout_constraintHeight_default="percent"
  • Then set the 然后设置layout_constraintWidth_percent or 或layout_constraintHeight_percent attributes to a value between 0 and 1 属性设置为0到1之间的值

You can also define one dimension of a widget as a ratio of the other one. In order to do that, you need to have at least one constrained dimension be set to 0dp (i.e., MATCH_CONSTRAINT), and set the attribute layout_constraintDimensionRatio to a given ratio. For example:

您还可以将小部件的一个维度定义为另一个维度的比率。为此,您需要将至少一个约束维度设置为0dp (即 MATCH _ constraint) ,并将属性 layout _ constraint/dimenratio 设置为给定的比例。例如:

will set the height of the button to be the same as its width. 将按钮的高度设置为与宽度相同

The ratio can be expressed either as:

这个比例可以表示为:

  • a float value, representing a ratio between width and height 一个浮点值,表示宽度和高度之间的比例
  • a ratio in the form “width:height” “ width: height”形式的比率

You can also use ratio if both dimensions are set to MATCH_CONSTRAINT (0dp). In this case the system sets the largest dimensions that satisfies all constraints and maintains the aspect ratio specified. To constrain one specific side based on the dimensions of another, you can pre append W," or H, to constrain the width or height respectively. For example, If one dimension is constrained by two targets (e.g. width is 0dp and centered on parent) you can indicate which side should be constrained, by adding the letter W (for constraining the width) or H (for constraining the height) in front of the ratio, separated by a comma:

如果两个维度都设置为 MATCH _ constraint (0dp) ,也可以使用 ratio。在这种情况下,系统设置满足所有约束的最大维,并维护指定的纵横比。要基于另一个的尺寸来约束一个特定的侧面,可以预先附加 w 或 h 来分别约束宽度或高度。例如,如果一个维度被两个目标约束(例如,宽度是0dp,以父节点为中心) ,你可以通过在比率前面加上字母 w (用于约束宽度)或 h (用于约束高度) ,用逗号分隔,来指明哪一边应该被约束:

will set the height of the button following a 16:9 ratio, while the width of the button will match the constraints to parent. 将按照16:9的比例设置按钮的高度,而按钮的宽度将匹配父节点的约束

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

ConstraintLayout

Chains provide group-like behavior in a single axis (horizontally or vertically). The other axis can be constrained independently.

链在一个轴(水平或垂直)中提供类似于组的行为。另一个轴可以独立约束。

A set of widgets are considered a chain if they are linked together via a bi-directional connection (see Fig. 9, showing a minimal chain, with two widgets).

如果一组窗口小部件通过双向连接连接在一起,那么它们就被认为是一个链(参见图9,显示了一个最小的链,有两个窗口小部件)。

ConstraintLayout

Fig. 9 - Chain 图9-链

Chains are controlled by attributes set on the first element of the chain (the “head” of the chain):

链是由链的第一个元素(链的“头”)的属性控制的:

ConstraintLayout

Fig. 10 - Chain Head 图10-链头

The head is the left-most widget for horizontal chains, and the top-most widget for vertical chains.

头部是水平链最左边的小部件,而垂直链最上边的小部件。

If margins are specified on connections, they will be taken in account. In the case of spread chains, margins will be deducted from the allocated space.

如果在连接上指定了边距,则将考虑这些边距。在扩展链的情况下,保证金将从分配的空间中扣除。

When setting the attribute layout_constraintHorizontal_chainStyle or layout_constraintVertical_chainStyle on the first element of a chain, the behavior of the chain will change according to the specified style (default is CHAIN_SPREAD).

当在链的第一个元素上设置属性 layout _ constrainthorizontal _ chainstyle 或 layout _ constraintinvertical _ chainstyle 时,链的行为将根据指定的样式(缺省值为 CHAIN _ spread)而改变。

  • CHAIN_SPREAD – the elements will be spread out (default style) – 元素将被分散(默认样式)
  • Weighted chain – in 加重链---- 英寸CHAIN_SPREAD mode, if some widgets are set to 如果一些窗口小部件被设置为MATCH_CONSTRAINT, they will split the available space ,他们将分裂的可用空间
  • CHAIN_SPREAD_INSIDE – similar, but the endpoints of the chain will not be spread out ——相似,但是链条的端点不会分散开来
  • CHAIN_PACKED – the elements of the chain will be packed together. The horizontal or vertical bias attribute of the child will then affect the positioning of
    the packed elements

——链条的各个部分将被包装在一起。然后,子元素的水平或垂直偏置属性将影响打包元素的位置

ConstraintLayout

Fig. 11 - Chains Styles 图11-链条样式

The default behavior of a chain is to spread the elements equally in the available space. If one or more elements are using MATCH_CONSTRAINT, they will use the available empty space (equally divided among themselves). The attribute layout_constraintHorizontal_weight and layout_constraintVertical_weight will control how the space will be distributed among the elements using MATCH_CONSTRAINT. For exemple, on a chain containing two elements using MATCH_CONSTRAINT, with the first element using a weight of 2 and the second a weight of 1, the space occupied by the first element will be twice that of the second element.

链的默认行为是在可用空间中平均分布元素。如果一个或多个元素正在使用 MATCH _ constraint,它们将使用可用的空白空间(在它们之间平均分配)。属性 layout _ constrainthorizontal _ weight 和 layout _ constrainintvertical _ weight 将控制如何使用 MATCH _ constraint 在元素之间分配空间。例如,在一个使用 MATCH _ constraint 包含两个元素的链上,第一个元素的权重为2,第二个元素的权重为1,第一个元素所占据的空间将是第二个元素的两倍。

When using margins on elements in a chain, the margins are additive.

当在链中的元素上使用页边距时,页边距是附加的。

For example, on a horizontal chain, if one element defines a right margin of 10dp and the next element defines a left margin of 5dp, the resulting margin between those two elements is 15dp.

例如,在水平链上,如果一个元素定义了10dp 的右边距,而下一个元素定义了5dp 的左边距,那么这两个元素之间的结果边距是15dp。

An item plus its margins are considered together when calculating leftover space used by chains to position items. The leftover space does not contain the margins.

一个项目加上它的利润是一起考虑时,计算剩余的空间使用的链定位项目。剩余的空间不包含页边空白。

In addition to the intrinsic capabilities detailed previously, you can also use special helper objects in ConstraintLayout to help you with your layout. Currently, the Guideline object allows you to create Horizontal and Vertical guidelines which are positioned relative to the ConstraintLayout container. Widgets can then be positioned by constraining them to such guidelines. In 1.1Barrier and Group were added too.

除了前面详细介绍的内在功能之外,您还可以在 ConstraintLayout 中使用特殊的 helper 对象来帮助您进行布局。目前,guidance 对象允许您创建相对于 ConstraintLayout 容器定位的 Horizontal 和 Vertical 指南。然后,可以通过约束小部件使其符合这些准则来定位它们。在1.1中,Barrier 和 Group 也被添加了。

In 1.1 we exposed the constraints optimizer. You can decide which optimizations are applied by adding the tag app:layout_optimizationLevel to the ConstraintLayout element.

在1.1中,我们公开了约束优化器。您可以通过将标记 app: layout _ optimizationlevel 添加到 constraint layout 元素来决定应用哪些优化。

  • none 没有 : no optimizations are applied : 不应用优化
  • standard 标准 : Default. Optimize direct and barrier constraints only : 默认值。仅优化直接约束和障碍约束
  • direct 直接的 : optimize direct constraints : 优化直接约束
  • barrier 障碍 : optimize barrier constraints : 优化障碍限制
  • chain 链 : optimize chain constraints (experimental) : 优化链约束(实验)
  • dimensions 尺寸 : optimize dimensions measures (experimental), reducing the number of measures of match constraints elements : 优化维度度量(实验) ,减少匹配约束元素的度量数量

This attribute is a mask, so you can decide to turn on or off specific optimizations by listing the ones you want. For example: app:layout_optimizationLevel=“direct|barrier|chain”

此属性是一个掩码,因此您可以通过列出所需的优化来决定是打开还是关闭特定的优化。例如: app: layout _ optimizationlevel = “ direct | barrier | chain”

托拉拽

ConstraintLayout

ConstraintLayout

相关标签: 开发高级技巧