什么是ConstraintLayout
你可以使用ConstraintLayout构建一个非常大且复杂的视图,而这些视图都是ConstraintLayout的直接子视图(不需要通过内嵌ViewGroup来实现)。它有点像RelativeLayout,通过互相之间或者和RelativeLayout的依赖关系来展示。但是ConstraintLayout比之更灵活,且更容易在Android Studio 视图编辑器使用,你可以在视图编辑器中直接拖拽控件来完成整个布局。
使用须知
使用ConstraintLayout需要满足两个条件
- Android 2.3 或者以上
- Android Studio 2.3 或者以上
添加依赖,在需要使用ConstraintLayout的module下面添加两段
repositories {
maven {
url 'https://maven.google.com'
}
}
dependencies {
compile 'com.android.support.constraint:constraint-layout:1.0.2' //这里的可能不是最新版本
}
如何开始ConstraintLayout
在旧布局中使用
](http://upload-images.jianshu.io/upload_images/5873376-5f53060ee56745b4.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
把LinearLayout转换成constraintlayout后,基本上还是会保持之前的布局展示,但是不排除出现意外情况。
上面是转换之前的Linearlayout
上面是转换之后的ConstraintLayout,我们可以发现,布局的展示保持了一致
直接从ConstraintLayout开始布局
Project窗口,New > XML > Layout XML,然后选中android.support.constraint.ConstraintLayout
作为Root Tag.下面是代码
<?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="match_parent">
</android.support.constraint.ConstraintLayout>
开发导读
相对位置
你可以布局一个新widget相对于另外一个存在的widget.这种相对关系包括x轴和y轴
- x轴:Left, Right, start, end
- y轴: top, bottom, text baseline
下面各种图形象描述上面的文字
可用的相对关系列表:
- layout_constraintLeft_toLeftOf: 当前widget的left对齐另外一个widget的left
- layout_constraintLeft_toRightOf :当前widget的left对齐另外一个widget的right
- layout_constraintRight_toLeftOf:** 当前widget的right对齐另外一个widget的left**
- layout_constraintRight_toRightOf:** 当前widget的right对齐另外一个widget的right**
- layout_constraintTop_toTopOf :当前widget的top对齐另外一个widget的top
- layout_constraintTop_toBottomOf:** 当前widget的top对齐另外一个widget的bottom**
- layout_constraintBottom_toTopOf:** 当前widget的bottom对齐另外一个widget的top**
- layout_constraintBottom_toBottomOf :当前widget的bottom对齐另外一个widget的bottom
- layout_constraintBaseline_toBaselineOf :**当前widget的baseline对齐另外一个widget的baseline, 使用与带文字的widget
- layout_constraintStart_toEndOf :当前widget的start对齐另外一个widget的end
- layout_constraintStart_toStartOf :当前widget的start对齐另外一个widget的start
- layout_constraintEnd_toStartOf :当前widget的end对齐另外一个widget的start
- layout_constraintEnd_toEndOf :当前widget的end对齐另外一个widget的end
上面B的Left对齐A的right,使用的 layout_constraintLeft_toRightOf
Margins
ConstraintLayout里可以使用marign(边距),查看源码,我们会发现ConstraintLayout的LayoutParams继承于MarginLayoutParams
public static class LayoutParams extends MarginLayoutParams {
.
}
和其他的layout一样,constraintlayout也可以使用如下几种margin
- android:layout_marginStart
- android:layout_marginEnd
- android:layout_marginLeft
- android:layout_marginTop
- android:layout_marginRight
- android:layout_marginBottom
比较特殊的是ConstraintLayout可以处理相对于gone widget的margin,和上面的对应关系一样
- layout_goneMarginStart
- layout_goneMarginEnd
- layout_goneMarginLeft
- layout_goneMarginTop
- layout_goneMarginRight
- layout_goneMarginBottom
我们用视图来对比一下
A显示的时候
A设置为GONE的时候
我们可以明显的发现,A设置GONE的时候,B的左边距明显和之前的相对于A的左边距不一样,这是因为我在B设置了如下属性
android:layout_marginStart="8dp"
app:layout_goneMarginStart="28dp"
A设置GONE的时候,app:layout_goneMarginStart="28dp"
起作用,所以我们上面看到的左边距显示的是28dp
居中位置和偏向位置
如何实现居中布局,如下图
代码是如何实现的:
<Button
android:id="@+id/button39"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="B"
android:layout_marginTop="8dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:layout_marginBottom="8dp"
app:layout_constraintStart_toStartOf="parent"
android:layout_marginStart="8dp"
app:layout_constraintEnd_toEndOf="parent"
android:layout_marginEnd="8dp"/>
偏向位置
包括两种
- layout_constraintHorizontal_bias 水平方向的偏向
- layout_constraintVertical_bias 垂直方向的偏向
layout_constraintHorizontal_bias
会作用于widget的left和right的位置
layout_constraintVertical_bias
会作用于widget的top和bottom的位置
使用效果图来说明下
对应的xml布局
.
app:layout_constraintVertical_bias="0.3"
.
尺寸限定
- android:minWidth 设置widget的最小宽度
- android:maxWidth 设置widget的最大宽度
- android:minHeight 设置widget的最小高度
- android:maxHeight 设置widget的最大高度
- 特定的尺寸,如:123dp
- WRAP_CONTENT
- 0dp ,等于
MATCH_CONSTRAINT
通过下图来分析WRAP_CONTENT
和MATCH_CONSTRAINT
- a:
WRAP_CONTENT
- b:
MATCH_CONSTRAINT
- c:
MATCH_CONSTRAINT
,margin="8dp"
Ratio比例
可以app:layout_constraintDimensionRatio
通过设置widget的宽和高的比例,必须满足layout_width
和layout_height
至少一个设置为0dp(MATCH_CONSTRAINT)
<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"/>
视图模式对应:
分析:
- W 限定宽度
- H 限定高度
- 16:9 对应 -> 宽度:高度
相对链
如上:我们创建了一个相对链,A和B会互相依赖于对方的相对位置
A 是"head of Chain", 它会控制整个相对链,也就是说B,C的位置都是通过A来调整的。
相对链中的边距
在下面中会提到的spread chains
,边距会分配的space中自动扣除
相对链的style(样式)
如上图所示:我们可以通过修改相对链的style来实现不同的布局方式,还是很强大的。
相对链中的权重(weight)
在ConstraintLayout,我们也可以像LinearLayout
一样使用权重来布局,
layout_constraintHorizontal_weight
和layout_constraintVertical_weight
会对使用了MATCH_CONSTRAINT
的widget起作用
-
layout_constraintHorizontal_weight
水平方向的相对链中的权重 -
layout_constraintVertical_weight
垂直方向中的相对链中的权重
Guideline
Guideline是帮助来调整布局的,它本身不会在视图中显示出来。
上面视图对应的xml布局
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
....
<android.support.constraint.Guideline
android:layout_width="0dp"
android:layout_height="0dp"
android:id="@+id/guideline"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.15" />
<android.support.constraint.Guideline
android:layout_width="0dp"
android:layout_height="0dp"
android:id="@+id/guideline2"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.85"
/>
<android.support.constraint.Guideline
android:layout_width="0dp"
android:layout_height="0dp"
android:id="@+id/guideline3"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.5" />
<android.support.constraint.Guideline
android:layout_width="0dp"
android:layout_height="0dp"
android:id="@+id/guideline4"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.15" />
<android.support.constraint.Guideline
android:layout_width="0dp"
android:layout_height="0dp"
android:id="@+id/guideline5"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.50097847" />
<android.support.constraint.Guideline
android:layout_width="0dp"
android:layout_height="0dp"
android:id="@+id/guideline6"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.85" />
</android.support.constraint.ConstraintLayout>
Guideline可以使用的属性
-
android:orientation
设置guideline的方向,horizontal
代表水平方向(从左到右),vertical
代表垂直方向(从上到下) -
app:layout_constraintGuide_percent
,guideline所在的百分比位置 -
app:layout_constraintGuide_begin
,guideline所在位置和起始边界的距离 -
app:layout_constraintGuide_end
,guideline所在位置和截止边界的距离
NOTE:当app:layout_constraintGuide_percent
和app:layout_constraintGuide_begin
(app:layout_constraintGuide_end
)都设置的时候,app:layout_constraintGuide_percent
优先
总结
使用ConstraintLayout可以有效的减小layout的层级深度, android-ConstraintLayoutExamples是google官方提供的关于demo
感谢