目录
前言
1.将ConstraintLayout添加到项目中
2.基本规则
3.示例讲解
3.1居中对齐
3.2 排列
3.3引导线Guideline
3.4计算器示例
3.5宽高比示例
3.6Chains链模式示例
3.7Barrier屏障示例
ConstraintLayout是目前Android Studio创建一个Activity的默认根布局。在Android training中也是排在布局中的第一位,足够体现重要性。
优点:是可以减少布局嵌套,弥补四大布局比较不好实现的地方,良好支持拖拽,良好支持UI可视化编辑。
缺点:ConstraintLayout作为ListView的Item根布局时设置Item元素可见性,不会触发onLayout,位置不更新。与传统列表结合使用,要慎重考虑。
本文以代码结合可视化UI编辑方式说明
1.1在module的build.gradle添加如下依赖
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
1.2在Project的build.gradle添加如下依赖
repositories {
google()
jcenter()
}
1.3在工具栏或同步通知中,点击 Sync Project with Gradle Files
注:如果sync 失败需要重复试几次
1.4将跟布局替换成 androidx.constraintlayout.widget.ConstraintLayout
2.1每个控件至少要两个约束条件:一个水平约束,一个垂直约束。
水平约束:
layout_constraintLeft_toLeftOf
layout_constraintLeft_toRightOf
layout_constraintRight_toLeftOf
layout_constraintRight_toRightOf
layout_constraintBaseline_toBaselineOf
layout_constraintStart_toEndOf
layout_constraintStart_toStartOf
layout_constraintEnd_toStartOf
layout_constraintEnd_toEndOf
垂直约束
layout_constraintTop_toTopOf
layout_constraintTop_toBottomOf
layout_constraintBottom_toTopOf
layout_constraintBottom_toBottomOf
2.2、无法将 match_parent
用于 ConstraintLayout
中的任何视图。请改用0dp即
“match constraints” 。
图1.1
3.1.1 顶部居中对齐
如图1.1中的“顶部居中按钮”
3.1.1.1代码实现
基于屏幕左右居中关键代码:
控件左侧约束到屏幕父布局的左侧
app:layout_constraintStart_toStartOf="parent"
控件右侧约束到屏幕右侧
app:layout_constraintEnd_toEndOf="parent"
控件顶部约束到tv_title的底部
app:layout_constraintTop_toBottomOf="@+id/tv_title"
3.1.1.2可视化编辑实现
从Palette中左键选中Button直接拖到界面中,放在顶部标题文字下,在可视化界面左键选中Button,即可看到右边的Attribute面板,如图1.2。点击左右两个蓝色加号按钮,设置0,点击顶部蓝色按钮设置80,这样设置完就可以自动生成上面三个约束的代码和marginTop。
图1.2
3.1.2 居于父容器正中间对齐
如图1.1中的“屏幕居中按钮”
3.1.2.1 代码实现
相对顶部居中多了一行底部约束到父容器底部
app:layout_constraintBottom_toBottomOf="parent"
另外 app:layout_constraintHorizontal_bias="0.5" 是基于父容器左右对齐,拖拽自动生成,可以去掉,后面会本章后面会说明。
3.1.2.2可视化编辑实现
左右两边点击两个蓝色加号并设置0间距,如果顶部和底部没有其他控件遮挡,可以点击上下两个蓝色加号,设置0间距即可,如图1.3。如果顶部和底部有其他空间就需要在Design可视化界面,选中空间顶部圆点拖到父容器顶部,生成约束线即成功,底部同理,如图1.4。关于具体操作视频,文章底部有官网文章有操作视频可以参考。
图1.3 图1.4
3.1.3 居于上下控件居中
如图1.1中的“居于上下控件居中”按钮
3.1.3.1 代码实现
3.1.3.2 可视化编辑实现
如图1.5 将Button拖到上下两个按钮中间,选中按钮,然后再Attributes的layout面板中点击上下左右蓝色加号并设置0间距。
图 1.5
图 1.6
3.2.1 代码实现
底部三个按钮的底部约束到父容器底部,左右两侧分别约束到左右两侧最近的控件,左侧没有控件就约束到父容器左侧如“底部2”的 app:layout_constraintStart_toStartOf="parent" ,右侧没有控件就约束到app:layout_constraintRight_toEndof="parent" ;
倒数第二行,“底部4”按钮底部约束到“底部2”按钮,“底部5”和“底部6”按钮分别基线对其左侧的控件,即文字保持在同一水平线,如app:layout_constraintBaseline_toBaselineOf 属性。
编辑框和按钮填满横向布局的情况,“Button”约束到父容器右侧;“Name”编辑框设置 android:layout_width="0dp",右侧约束到“Button”左侧,左侧约束到父容器左侧。
3.2.2 可视化编辑
如图1.7 ,鼠标左键按住圆点拖动到要约束的目标位置即可自动生成约束代码。基线对齐需要:右键点击要约束的文本视图,然后点击Show Baseline就会看到控件内部出现圆角矩形,左键按住这个圆角矩形,拖到目标的基线位置(圆角矩形)即可实现基线对齐。在周围控件正好是要约束的目标控件时,可以直接使用3.1.1.2的方式直接点击蓝色加号按钮添加约束。
图1.7
引导线用途:
您可以添加垂直或水平约束引导线约束视图,并且用户看不到该引导线。
您可以根据相对于布局边缘的dp单位或百分比在布局中定位引导线。
3.3.1 Guideline的关键属性
android:orientation="horizontal" 横向
android:orientation="vertical" 纵向
app:layout_constraintGuide_percent="0.5" 按父容器比例决定Guideline位置,0.5为中间位置
app:layout_constraintGuide_begin="157dp" 距离开始位置的距离决定Guideline的位置
app:layout_constraintGuide_end="128dp" 距离结束位置的距离决定Guideline的位置
如果是横向:开始位置位左边,结束位置位右边。如果是纵向:开始位置为顶部,结束位置位底部。
上面三个决定Guideline位置属性是互斥的,只能选择合适的一个。
3.3.2 Guideline的可视化操作
在布局的xml的Design模式右键->Helpers->Add Vertical Guideline或Add Horizontal Guideline即可添加横向或纵向引导线。如图1.8
调整定位模式:将鼠标放在引导线边缘图标(可能是百分号或实心三角形),点击即可切换自动切换app:layout_constraintGuide_percent、app:layout_constraintGuide_begin和app:layout_constraintGuide_end。如图1.9
调整引导线的位置:将鼠标放在引导线上,出现双向箭头即可拖拽。如图2.0
如图1.8
图1.9
图2.0
3.4.1实现逻辑
纵向:从计算结果显示的TextView到按钮7、按钮4、按钮1和按钮.都是顶部约束到顶部最近的控件、底部约束到底部最近的控件。
横向:从左到右,依次左侧约束到左侧最近的控件,右侧约束到右侧最近的控件。从左侧第二个控件开始底部对齐前一个控件,如图中的按钮7、按钮8和按钮9。
约束布局默认添加间距的特性,可以在再横向和纵向将控件剩余的控件平均分配到每个控件的间隙。这种默认添加间距的特性可以通过chainStyle改变,下面章节会详细介绍。
图2.1
完整实现代码:
3.4.2计算器的可视化编辑实现可以参照3.1.2.2
显示效果如图2.2
图2.2
3.5.1 代码实现
宽高比使用场景:如图2.2 图片横向填满屏幕,整张图的比例保持不变。在没有约束布局的情况下,需要去计算屏幕的宽度,然后根据要显示图片的比例计算出图片的显示高度。现在如果父容器是约束布局,就可以在目标控件设置app:layout_constraintDimensionRatio属性。
如图中的大图就设置了
app:layout_constraintDimensionRatio="h,16:9" 宽比高 16:9
换个属性值实现同样的效果:
app:layout_constraintDimensionRatio="w,9:16" 宽比高 16:9
注意1:宽高必须设置0dp
android:layout_width="0dp"
android:layout_height="0dp"
大图的布局代码
注意2:设置宽高比的目标控件宽高是可确定的。如图2.2中安卓机器人图标的上下左右都需要约束,漏掉一个控件就不能正常显示。如下面代码:去掉app:layout_constraintBottom_toBottomOf控件就无法显示了。
3.5.2 宽高比可视化编辑实现
首先将宽高设置0dp,然后在布局的Design选中目标控件,就可以在Arrtibutes面板的Layout类别中看到控件正方形左上角多了一个内三角形如图2.3,单击即可默认实现1:1比例。如图2.4。设置ratio比例内容即可。
图2.3
图2.4
显示效果如图2.5
图2.5
3.6.1设置Chain链模式关键要点
1、关键属性
app:layout_constraintHorizontal_chainStyle 只需要设置排列的第一个,如图2.5中只有按钮1、按钮4和按钮7设置了该属性。
2、属性值效果
spread 如图2.5中的按钮1、按钮2和按钮3。另外这也是缺省值。没有设置上述属性也是spread的效果。
spread_inside 如图2.5中的按钮4、按钮5和按钮6。第一个和最后一个与父容器没有间距。排列的控件之间有间距。
packed 如图2.5中的按钮7、按钮8和按钮9。第一个和最后一个与父容器有间距。排列的控件之间无间距。
完整代码:
3.6.1实现Chain模式可视化编辑
在布局中右键选中排列中的任意控件->Cycle Chain mode 如图2.6,即可实现ChainMode在spread、spread_inside和packed切换。
图2.6
屏障顾名思义就是将一堆控件挡住。要挡在哪个方向是可以设置的。
图2.7
3.7.1代码实现Barrier屏障
往布局中添加
androidx.constraintlayout.widget.Barrier控件
设置app:barrierDirection屏障方向属性,这个值是相对于被屏障挡住控件的。可选值:left、right、top、bottom、start、end。
参考:
https://developer.android.google.cn/training/constraint-layout
https://developer.android.google.cn/reference/androidx/constraintlayout/widget/ConstraintLayout
https://www.jianshu.com/p/17ec9bd6ca8a
https://blog.csdn.net/guolin_blog/article/details/53122387