ConstraintLayout
public class ConstraintLayout
extends ViewGroup
java.lang.Object继承 | |||
↳ | android.view.View | ||
↳ | android.view.ViewGroup | ||
↳ | android.support.constraint.ConstraintLayout |
注意: ConstraintLayout
作为支持库提供,您可以在API级别9(Gingerbread)开始的Android系统上使用。因此,我们计划随着时间的推移丰富其API和功能。本文档将反映这些更改。
您目前可以使用各种类型的约束:
请注意,您不能在约束中具有循环依赖关系。
另请参阅ConstraintLayout.LayoutParams
布局属性
开发者指南
相对定位
相对定位是在ConstraintLayout中创建布局的基本构建块之一。这些约束允许您将给定的小部件相对于另一个小部件进行定位。您可以在水平和垂直轴上约束小部件:
- 水平轴:左,右,起点和终点
- 垂直轴:顶部,底部和文本基线
一般概念是将窗口小部件的给定侧约束到任何其他窗口小部件的另一侧。
例如,为了将按钮B定位在按钮A的右侧(图1):
图1 - 相对定位示例
你需要这样做:
<Button android:id="@+id/buttonA" ... /> <Button android:id="@+id/buttonB" ... app:layout_constraintLeft_toRightOf="@+id/buttonA" />
这告诉系统我们希望按钮B的左侧被约束到按钮A的右侧。这样的位置约束意味着系统将尝试让双方共享相同的位置。
以下是可用约束的列表(图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
它们都引用id
另一个小部件,或者parent
引用父容器,即ConstraintLayout:
<Button android:id="@+id/buttonB" ... app:layout_constraintLeft_toLeftOf="parent" />
边距
图3 - 相对定位边距
如果设置了边距,则它们将应用于相应的约束(如果存在)(图3),将边距强制为目标和源边之间的空间。通常的布局边距属性可用于此效果:
android:layout_marginStart
android:layout_marginEnd
android:layout_marginLeft
android:layout_marginTop
android:layout_marginRight
android:layout_marginBottom
请注意,保证金只能是正数或等于零,并且需要a Dimension
。
连接到GONE小部件时的边距
当位置约束目标的可见性为View.GONE
,您还可以使用以下属性指示要使用的不同边距值:
layout_goneMarginStart
layout_goneMarginEnd
layout_goneMarginLeft
layout_goneMarginTop
layout_goneMarginRight
layout_goneMarginBottom
居中定位和偏见
一个有用的方面ConstraintLayout
是它如何处理“不可能”的约束。例如,如果我们有类似的东西:
<android.support.constraint.ConstraintLayout ...> <Button android:id="@+id/button" ... app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent/> </>
除非ConstraintLayout
恰好具有Button
与之完全相同的大小,否则两个约束不能同时满足(双方都不能成为我们想要它们的地方)。
在这种情况下发生的事情是,约束的作用就像是相反的力量将小部件拉平(图4); 这样小部件最终将在父容器中居中。这同样适用于垂直约束。
偏压
遇到这种相反的约束时的默认设置是使窗口小部件居中; 但是您可以使用偏差属性调整定位以使一侧偏向另一侧:
layout_constraintHorizontal_bias
layout_constraintVertical_bias
例如,以下将使左侧具有30%的偏差而不是默认的50%,使得左侧将更短,小部件更倾向于左侧(图5):
<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中增加)
您可以以角度和距离约束窗口小部件中心相对于另一个窗口小部件中心。这允许您将小部件放在圆上(参见图6)。可以使用以下属性:
layout_constraintCircle
:引用另一个小部件IDlayout_constraintCircleRadius
:到其他小部件中心的距离layout_constraintCircleAngle
:小部件应该处于哪个角度(以度为单位,从0到360)
图6 - 圆形定位
<Button android:id="@+id/buttonA" ... /> <Button android:id="@+id/buttonB" ... app:layout_constraintCircle="@+id/buttonA" app:layout_constraintCircleRadius="100dp" app:layout_constraintCircleAngle="45" />
可见性行为
ConstraintLayout
具有标记为小部件的特定处理View.GONE
。
GONE
像往常一样,窗口小部件不会显示,也不是布局本身的一部分(即如果标记为,它们的实际尺寸将不会更改GONE
)。
但就布局计算而言,GONE
小部件仍然是其中的一部分,具有重要的区别:
- 对于布局传递,它们的尺寸将被视为零(基本上,它们将被解析为一个点)
- 如果他们对其他小部件有限制,他们仍然会受到尊重,但任何边距都会等于零
这种特定的行为允许构建布局,您可以暂时将窗口小部件标记为GONE
,而不会破坏布局(图7),这在进行简单的布局动画时尤其有用。
注意:使用的边距将是B在连接到A时定义的边距(例如,参见图7)。在某些情况下,这可能不是您想要的余量(例如A在其容器侧面有100dp的边距,B只有16dp到A,A标记为已消失,B将对容器有16dp的余量)。因此,您可以指定在连接到标记为已消失的窗口小部件时要使用的备用边距值(请参阅上面有关已删除边距属性的部分)。
尺寸限制
ConstraintLayout上的最小尺寸
您可以为ConstraintLayout
自身定义最小和最大尺寸:
android:minWidth
设置布局的最小宽度android:minHeight
设置布局的最小高度android:maxWidth
设置布局的最大宽度android:maxHeight
设置布局的最大高度
ConstraintLayout
当尺寸设置 为时,将使用这些最小和最大尺寸
WRAP_CONTENT
。
小部件维度约束
可以通过以3种不同方式设置android:layout_width
和 android:layout_height
属性来指定小部件的维度:
- 使用特定维度(文字值,例如
123dp
或Dimension
参考) - 使用
WRAP_CONTENT
,这将要求小部件计算自己的大小 - 使用
0dp
,相当于“MATCH_CONSTRAINT
”
重要提示: MATCH_PARENT
不建议用于a中包含的小部件ConstraintLayout
。可以通过使用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
和layout_constraintHeight_min
:将设置此维度的最小大小layout_constraintWidth_max
和layout_constraintHeight_max
:将设置此维度的最大大小layout_constraintWidth_percent
和layout_constraintHeight_percent
:将此维度的大小设置为父级的百分比
最小和最大
为min和max指示的值可以是Dp中的维度,也可以是“wrap”,它将使用与其相同的值WRAP_CONTENT
。
百分比
要使用百分比,您需要设置以下内容:- 尺寸应设置为
MATCH_CONSTRAINT
(0dp) - 默认值应设置为百分比
app:layout_constraintWidth_default="percent"
或app:layout_constraintHeight_default="percent"
(注意:这在1.1-beta1和1.1-beta2中是必需的,但如果定义了percent属性,则在以下版本中不需要) - 然后将
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" />
将按钮的高度设置为与其宽度相同。
该比率可表示为:
- 浮点值,表示宽度和高度之间的比率
- “宽度:高度”形式的比率
如果两个尺寸都设置为MATCH_CONSTRAINT
(0dp),您也可以使用比率。在这种情况下,系统设置满足所有约束的最大尺寸并保持指定的纵横比。要根据另一个特定边的尺寸限制一个特定边,可以预先附加W,
“或” H,
分别约束宽度或高度。例如,如果一个尺寸受两个目标约束(例如,宽度为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的比例设置按钮的高度,而按钮的宽度将匹配父项的约束。
链
链在单个轴(水平或垂直)上提供类似行的行为。另一个轴可以独立约束。
创建一个链
如果一组小部件通过双向连接链接在一起,则它们被视为链(参见图9,显示最小链,具有两个小部件)。
链头
链由链的第一个元素(链的“头部”)上设置的属性控制:
头部是水平链的最左侧小部件,垂直链的最顶部小部件。
链中的边距
如果在连接上指定了边距,则会考虑它们。在扩散链的情况下,将从分配的空间中扣除保证金。
链式
设置属性layout_constraintHorizontal_chainStyle
或layout_constraintVertical_chainStyle
链的第一个元素时,链的行为将根据指定的样式(默认值CHAIN_SPREAD
)更改。
CHAIN_SPREAD
- 元素将展开(默认样式)- 加权链接
CHAIN_SPREAD
模式,如果设置了一些小部件MATCH_CONSTRAINT
,它们将分割可用空间 CHAIN_SPREAD_INSIDE
- 类似,但链的端点不会分散CHAIN_PACKED
- 链条的元素将被包装在一起。然后,子项的水平或垂直偏差属性将影响打包元素的定位
加权链
链的默认行为是在可用空间中平均分布元素。如果使用了一个或多个元素MATCH_CONSTRAINT
,它们将使用可用的空白空间(在它们之间平均分配)。属性layout_constraintHorizontal_weight
和layout_constraintVertical_weight
将控制如何将空间利用的元素之间进行分配MATCH_CONSTRAINT
。例如,在包含两个元素的链上使用MATCH_CONSTRAINT
,第一个元素使用权重2,第二个元素使用权重1,第一个元素占用的空间将是第二个元素占用的空间的两倍。
边距和链条(1.1)
在链中的元素上使用边距时,边距是相加的。
例如,在水平链上,如果一个元素定义了10dp的右边距而下一个元素定义了5dp的左边距,则这两个元素之间产生的边距为15dp。
在计算链用于定位项目的剩余空间时,会同时考虑项目及其边距。剩余空间不包含边距。
虚拟助手对象
除了之前详述的内在功能外,您还可以使用特殊的辅助对象ConstraintLayout
来帮助您进行布局。目前,该Guideline
对象允许您创建相对于ConstraintLayout
容器定位的水平和垂直指南。然后可以通过将小部件约束到这样的指导来定位小部件。在1.1中,Barrier
也Group
被添加了。
优化器(1.1)
在1.1中我们暴露了约束优化器。您可以通过将标记app:layout_optimizationLevel添加到ConstraintLayout元素来决定应用哪些优化。
- none:未应用任何优化
- 标准:默认。仅优化直接和障碍约束
- 直接:优化直接约束
- 障碍:优化障碍限制
- 链:优化链约束(实验)
- 维度:优化维度度量(实验),减少匹配约束元素的度量数量
此属性是一个掩码,因此您可以通过列出所需的优化来决定打开或关闭特定的优化。例如:app:layout_optimizationLevel =“direct | barrier | chain”
也可以看看:
概要
嵌套类 | |
---|---|
class | ConstraintLayout.LayoutParams 此类包含指定视图如何在其中布局的不同属性 |
继承的常量 |
---|
字段 | |
---|---|
protectedConstraintLayoutStates | mConstraintLayoutSpec |
继承的字段 |
---|
公共建设者 | |
---|---|
ConstraintLayout(Context context) | |
ConstraintLayout(Context context, AttributeSet attrs) | |
ConstraintLayout(Context context, AttributeSet attrs, int defStyleAttr) |
公共方法 | |
---|---|
int | getMaxHeight() 此视图的最大高度。 |
int | getMaxWidth() |
int | getMinHeight() 此视图的最小高度。 |
int | getMinWidth() 此视图的最小宽度。 |
int | getOptimizationLevel() 返回布局分辨率的当前优化级别 |
void | loadLayoutDescription(int layoutDescription) |
void | requestLayout() |
void | setConstraintSet(ConstraintSet set) 设置ConstraintSet对象以管理约束。 |
void | setMaxHeight(int value) 设置此视图的最大高度 |
void | setMaxWidth(int value) 设置此视图的最大宽度 |
void | setMinHeight(int value) 设置此视图的最小高度 |
void | setMinWidth(int value) 设置此视图的最小宽度 |
void | setOnConstraintsChanged(ConstraintsChangedListenerconstraintsChangedListener) |
void | setOptimizationLevel(int level) 设置布局分辨率的优化。 |
void | setState(int id, int screenWidth, int screenHeight) 设置ConstraintLayout的状态,使其加载特定的ConstraintSet。 |
受保护的方法 | |
---|---|
bo | checkLayoutParams(ViewGroup.LayoutParams p) |
Co | |
V | generateLayoutParams(ViewGroup.LayoutParams p) |
v | onLayout(boolean changed, int left, int top, int right, int bottom) |
v | onMeasure(int widthMeasureSpec, int heightMeasureSpec) |
继承方法 | |
---|---|
字段
公共建设者
ConstraintLayout
参数 | |
---|---|
context | Context |
attrs | AttributeSet |
ConstraintLayout
参数 | |
---|---|
context | Context |
attrs | AttributeSet |
defStyleAttr | int |
公共方法
getMaxWidth
返回 | |
---|---|
int |
getOptimizationLevel
返回布局分辨率的当前优化级别
返回 | |
---|---|
int | 目前的水平 |
loadLayoutDescription
参数 | |
---|---|
layoutDescription | int |
requestLayout
setConstraintSet
设置ConstraintSet对象以管理约束。ConstraintSet会覆盖子视图的LayoutParams。
参数 | |
---|---|
set | ConstraintSet :使用ConstraintSet布局子项 |
setMaxHeight
设置此视图的最大高度
setMaxWidth
设置此视图的最大宽度
setMinHeight
设置此视图的最小高度
setMinWidth
设置此视图的最小宽度
setOnConstraintsChanged
参数 | |
---|---|
constraintsChangedListener | ConstraintsChangedListener |
setOptimizationLevel
设置布局分辨率的优化。
优化可以是以下任何一种:
- Optimizer.OPTIMIZATION_NONE
- Optimizer.OPTIMIZATION_STANDARD
- 由特定优化组成的掩码
- Optimizer.OPTIMIZATION_DIRECT
- Optimizer.OPTIMIZATION_BARRIER
- Optimizer.OPTIMIZATION_CHAIN(实验性)
- Optimizer.OPTIMIZATION_DIMENSIONS(实验性)
参数 | |
---|---|
level | int :优化级别 |
的setState
设置ConstraintLayout的状态,使其加载特定的ConstraintSet。对于具有变体的状态,将选择具有匹配的宽度和高度约束的变体
参数 | |
---|---|
id | int :设置状态宽度和高度 |
screenWidth | int :屏幕的宽度(以像素为单位) |
screenHeight | int :屏幕的高度(以像素为单位) |
受保护的方法
checkLayoutParams
参数 | |
---|---|
p | ViewGroup.LayoutParams |
返回 | |
---|---|
boolean |
generateLayoutParams
参数 | |
---|---|
p | ViewGroup.LayoutParams |
onLayout
参数 | |
---|---|
changed | boolean |
left | int |
top | int |
right | int |
bottom | int |
onMeasure
参数 | |
---|---|
widthMeasureSpec | int |
heightMeasureSpec | int |