ConstraintLayout 可用的约束 (constraint-layout:1.0.2)
- 相对定位
- 边距(Margins)
- 中心定位
- 可见性行为(View.GONE)
- 链(Chains)
- 虚拟助手对象(Guideline)
相对定位
相对定位是 ConstraintLayout 创建布局的基本组成部分之一。这些约束允许你指定控件相对于另一个位置。
例如,按钮 B 要位于按钮 A 的右边
<Button
android:id="@+id/buttonA"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="ButtonA"/>
<Button
android:id="@+id/buttonB"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="ButtonB"
app:layout_constraintLeft_toRightOf="@id/buttonA"/>
可用的约束属性:
-
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)
边距
与 RelativeLayout 一样。属性列表
-
android:layout_marginStart
-
android:layout_marginEnd
-
android:layout_marginLeft
-
android:layout_marginTop
-
android:layout_marginRight
-
android:layout_marginBottom
与 RelativeLayout 不一样的是,当约束目标_visibility_属性设为 GONE 时,你还可以通过下面的属性设定边距:
-
layout_goneMarginStart
-
layout_goneMarginEnd
-
layout_goneMarginLeft
-
layout_goneMarginTop
-
layout_goneMarginRight
-
layout_goneMarginBottom
如下面的例子:
<android.support.constraint.ConstraintLayout ...>
<Button
android:id="@+id/buttonA" ...
android:visibility="gone"/>
<Button
android:id="@+id/buttonB" ...
app:layout_goneMarginStart="20dp"
app:layout_constraintLeft_toRightOf="@id/buttonA"/>
</android.support.constraint.ConstraintLayout>
当 buttonA 设成 gone 时,buttonA 消失,buttonB 距左边 20dp。注意,该属性只在约束目标设成 GONE 时生效,设成_visible_ 和 invisible 时该属性不起作用。
中心定位和偏移
怎么使控件居中呢?可以这样
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto">
<Button
android:id="@+id/buttonA"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="ButtonA"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"/>
</android.support.constraint.ConstraintLayout>
layout_constraintLeft_toLeftOf 和 layout_constraintRight_toRightOf 同时起作用,约束像相反的力左右拉动控件,使得部件将最终被居中在父容器。这同样适用于垂直约束。
这种情况下,默认使控件居中。但你可以使用下面的属性使控件的位置发生偏移。
- layout_constraintHorizontal_bias
- layout_constraintVertical_bias
例如,下面的设置会使控件往左偏移 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/>
</android.support.constraint.ConstraintLayout>
尺寸限制
当 ConstraintLayout 的大小被设置成 WRAP_CONTENT 时,可以使用
- android:minWidth (最小宽度)
- android:minHeight (最小高度)
来进行限制
容器内的控件 android:layout_width 和 android:layout_height 有 3 种情况:
- 使用具体的尺寸
- 使用 WRAP_CONTENT
- 使用 0dp,这是相当于“ MATCH_CONSTRAINT”
注意!ConstraintLayout 内的控件尽量不要使用 match_parent!
前两种与其他的布局类似,最后一种是通过其他的约束条件来确定控件的大小。
下面的代码使 buttonA 左边距父容器 50dp,右边铺满剩下的空间。
<android.support.constraint.ConstraintLayout ...>
<Button
android:id="@+id/buttonA"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="ButtonA"
android:layout_marginStart="50dp"
android:layout_marginLeft="50dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent" />
</android.support.constraint.ConstraintLayout>
当容器内的控件的长或者宽设为 0dp 时,可以通过 layout_constraintDimentionRatio 设置此控件的长宽比。
例如:
<Button
android:id="@+id/buttonA"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:text="测试文字排列"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintDimensionRatio="16:9"/>
效果如下:
按钮的 宽度:高度 = 16:9 。(也可以用浮点值,表示宽度和高度之间的比率)
当宽和高都设为 0dp 时,系统将设置最大尺寸满足所有约束并保持设定的长宽比。上面的例子将 android:layout_width 改为 0dp 后效果如下:
也可以通过预先添加 W 或“H”来分别限制宽度或高度。上面的效果图代码如下:
<Button
android:id="@+id/buttonA"
android:layout_width="0dp"
android:layout_height="0dp"
android:text="测试文字排列"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintDimensionRatio="h,16:9"/>
app:layout_constraintDimensionRatio=”h,16:9” 意思是通过 16:9 的比例设置 button 的高度。
感觉这个地方的 w 和 h 的设置有点难以理解,事实上,”w”或者”h”完全可以不用设置,布局可以自动推断。例如,上面的代码约束了宽度,使宽度铺满容器,而高度并没有约束,那么高度就会根据比例自动调整。
Chains
Chains 为同一方向上(水平或垂直)相互连接(或者说约束)的控件提供统一的管理。
Chains 的属性由这条 chain 上第一个控件所控制,该控件称为 chain head。
上图中控件 A 左边与父容器接触,右边与控件 B 依赖;控件 B 左边依赖于控件 A,右边依赖于控件 B;控件 C 左边依赖于控件 B,右边依赖于父容器。且该 chain 为水平方向。
用代码表示如下:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<Button
android:id="@+id/buttonA"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="buttonA"
app:layout_constraintHorizontal_chainStyle="spread"
app:layout_constraintRight_toLeftOf="@id/buttonB"
app:layout_constraintLeft_toLeftOf="parent"/>
<Button
android:id="@+id/buttonB"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="buttonB"
app:layout_constraintLeft_toRightOf="@+id/buttonA"
app:layout_constraintRight_toLeftOf="@id/buttonC"/>
<Button
android:id="@+id/buttonC"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="buttonC"
app:layout_constraintLeft_toRightOf="@+id/buttonB"
app:layout_constraintRight_toRightOf="parent"/>
</android.support.constraint.ConstraintLayout>
效果图:
由于 ButtonA 为 chain head。所以 layout_constraintHorizontal_chainStyle 由 ButtonA 设置。该属性表示水平方向的 chain。还有另一个属性 layout_constraintVertical_chainStyle 表示垂直方向。
该属性有三种值:
-
spread 默认值。均匀分布(控件宽为 wrap_content 或确定值)
-
spread_inside 与 spread 类型,只是 chain 两端的控件不占父容器的空间,多余的空间由 chain 里的控件平分。
-
spread_inside chain 上的所有控件居中紧挨在一起
效果图如下:
当设置 spread 时,可以分别为每个子控件设置权重,对应的属性为 layout_constraintHorizontal_weight 和 layout_constraintVertical_weight,与 LinearLayout 的 weight 类似,需要注意的是,此时子控件的 layout_width 需要设成 0dp。
当设置 packed 时,可以设置 chain 在水平或垂直方向上的偏移量,对应的属性为 layout_constraintHorizontal_bias 和 layout_constraintVertical_bias,取值在 0 到 1 之间。
Guideline
ConstraintLayout 还可以通过创建对象 guideline 来辅助布局。
Guideline 有水平和垂直两张情况:
- 水平(horizontal)的 Guideline 高度为 0,宽度是 ConstraintLayout 的宽度
- 垂直(vertical)的 Guideline 宽度为 0,高度是 ConstraintLayout 的高度
Guideline 创建方式:
<android.support.constraint.Guideline
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/guideline"
app:layout_constraintGuide_begin="52dp"
android:orientation="vertical" />
Guideline 有三种属性:
- layout_constraintGuide_begin 距离左侧或顶部的距离
- layout_constraintGuide_end 距离右侧或底部的距离
- layout_constraintGuide_percent float 类型。距离 left 或 top 的比例。
示例:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<android.support.constraint.Guideline
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/guideline"
app:layout_constraintGuide_begin="52dp"
android:orientation="vertical" />
<Button
android:id="@+id/buttonA"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="buttonA"
app:layout_constraintLeft_toRightOf="@+id/guideline" />
</android.support.constraint.ConstraintLayout>
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于