约束布局的用法
ConStraintlayout是android.view.ViewGroup,允许我们灵活的定位和调整窗口小部件的大小。
当前可以使用多种约束:
- Relative positioning(相对定位)
- Margins(相对定位余量)
- Centering positioning(居中定位)
- Circular positioning(圆形定位)
- Visblity behavior(可见性行为)
- Dimension constrains(尺寸限制)
- Chains(链条)
- Virtual Helpers objects(虚拟助手对象)
- Optimizer(优化器)
相对定位
可以在水平和垂直轴上约束小部件。
- 水平轴:左、右、起点和终点
- 垂直轴:顶部、底部和文本基线
下图是将按钮B定位在按钮A的右侧(采用官网图片):
相对定位
<Button
android:id="@+id/buttonA"
... />
<Button
android:id="@+id/buttonB"
...
app:layout_constraintLeft_toRightOf="@+id/buttonA"/>
这种方式告诉系统我们希望将按钮B的左侧限制为按钮A的右侧,这种位置限制意味着系统将尝试使两侧共享同一位置。
image
可用约束列表如下:
- 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)
Margins
image如果设置了边距,则会将他们应用于相应的约束,从而将边距强制为目标端与源端之间的空间。可以使用通常的布局边距属性来达到此效果:
- android:layout_marginStart
- android:layout_marginEnd
- android:layout_marginLeft
- android:layout_marginTop
- android:layout_marginRight
- android:layout_marginBottom
连接到GONE小部件时的边距
当位置限制目标的可见性为View.GONE,可以使用下面属性设置其他边距值:
- layout_goneMarginStart
- layout_goneMarginEnd
- layout_goneMarginLeft
- layout_goneMarginRight
- layout_goneMarginTop
- layout_goneMarginBottom
居中定位和偏向
有以下代码:
<android.support.constraintlayout.widget.ConstraintLayout ...>
<Button android:id="@+id/button" ...
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent/>
</android.support.constraint.ConstraintLayout>
除非ConStraintLayout碰巧大小和Button完全相同,否则无法同时满足两个约束。
image
这种情况下,约束的作用就像反向作用力一样将小部件平均拉开。这样小部件将最终位于父容器的中心。类似的应用于垂直约束。
偏压
上面是居中定位,如果想让小部件偏到另一侧,可以使用bias属性调整位置。
- layout_constrainHorizontal
-
layout_constrainVertical_bias
image
如下代码,使左侧具有30%的偏差,而不是默认的50%,这样左侧将更短,小部件更偏向左侧。
<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/>
</>
通过使用偏见,可以更好的适应屏幕尺寸变化的用户界面。
圆形定位
可以以一定角度和距离相对于另一个窗口小部件中心限制窗口小部件中心,这可以使小部件放在圆上,使用如下属性:
- layout_constraintCircle:引用另一个小部件
- layout_constraintCircleRadius:到另一个小部件中心的距离
-
layout_constraintCircleAngle:小部件应处于哪个角度
image
<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小部件仍然是其中的一部分,但是有一个重要的区别:
- 对于布局传递,其尺寸将被视为0(基本上会被解析为一个点)
-
如果他们对其他小部件有约束,则他们仍然会受到尊重,但是任何边距都等于0。
image
尺寸限制
最小尺寸
使用wrap_content的时候,可以使用如下来限制控件大小。
- android:minWidth 设置布局的最小宽度
- android:minHeight 设置布局的最小高度
- android:maxWidth 设置布局的最大宽度
- android:maxHeigth 设置布局的最大高度
小部件尺寸约束
可以通过3种不同的方式设置android:layout_widht和android:layout_height属性来指定小部件的尺寸:
- 使用特定尺寸
- 使用wrap_content,这要求小部件计算自己的大小
- 使用0dp,等同于match_constraint
不建议ConstraintLayout布局中包含的小部件用match_partent,可通过match_constraint将相应的左/右或上/下约束设置来实现类似parent的行为。
match_constraint
将尺寸设置为match_constraint,默认是占用所有可用空间,可使用其他几个修饰符:
- layout_constraintWidth_min和layout_constraintHeight_min:将为此尺寸设置最小尺寸
- layout_constraintWidth_max和layout_constraintHeight_max:将为此尺寸设置最大尺寸
- layout_constraintWidth_percent和layout_constraintHeight_percent:将此尺寸的尺寸设置为父尺寸的百分比
尺寸百分比
使用方法:
- 尺寸应设置为MATCH_CONSTRAINT(0dp)
- 默认值应设置为百分比app:layout_constraintWidth_default="percent" 或app:layout_constraintHeight_default="percent"
- 然后将layout_constraintWidth_percent or layout_constraintHeight_percent属性设置为介于0和1之间的值
宽高比
可以将小部件的一个尺寸定义为另一个尺寸的比例,所以至少将一个约束尺寸设置为0dp,通过属性layout_constraintDimensionRation设置为给定的比率。例如:
<Button android:layout_width="wrap_content"
android:layout_height="0dp"
app:layout_constraintDimensionRatio="1:1"/>
将按钮的高度设置为与按钮的宽度相同。
该比率可以表示为:
- 浮点值,表示宽度和高度之间的比率
- 形式为“宽度:高度”的比率
如果两个尺寸都为match_constraint,系统将设置满足所有约束并维持指定长宽比的最大尺寸。
假设控件A在水平的左右方向都存在约束,垂直方向只有一条约束。相对于垂直方向,A在水平方向上的宽度比较固定(等于屏幕宽度),所以高度会根据比例跟着变化。
假设控件A在水平方向以及垂直方向都有存在约束,那就可以通添加w或h来指定约束方向。
app:layout_constraintDimensionRatio="w,1:2" //或 "h,1:2"
"w,1:2"表示 宽度根据高度变化而变化,且宽高比依旧是1:2
"h,1:2"表示 高度根据宽度变化而变化,且宽高比依旧是1:2
W/H 是用于指定约束方向
Chain
链式表示方式就类似于水平方向、垂直方向上小部件按比重分配空间,具体类型可见下图:
image
通过layout_constraintHorizontal_weight属性来达到不同的效果。
layout_constraintVertical_chainStyle = "spread_inside|spread|packed"
实现spread效果代码如下:
<Button
android:id="@+id/buttonA"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="buttonA"
app:layout_constraintEnd_toStartOf="@+id/buttonB"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintHorizontal_weight="1"
app:layout_constraintStart_toStartOf="parent"
tools:ignore="MissingConstraints" />
<Button
android:id="@+id/buttonB"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="buttonB"
app:layout_constraintEnd_toStartOf="@+id/buttonC"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintHorizontal_weight="1"
app:layout_constraintStart_toEndOf="@+id/buttonA"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="MissingConstraints" />
<Button
android:id="@+id/buttonC"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="buttonC"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintHorizontal_weight="1"
app:layout_constraintStart_toEndOf="@+id/buttonB"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="MissingConstraints" />
可以用chain工具自动生成布局代码。刚开始手动写的时候没有加bias属性布局没有反应。
网友评论