我们在编写复杂页面的时候,一般使用RL控件。现在我们可以尽量使用ConstraintLayout进行替换,效率高,更加方便布局,性能也更好。而且相对于RelativeLayout,他更加灵活,比如RL的子控件假如是layout_centerHorizontal
或者是类似的定义了之后,他们其他子控件参照与该控件的那些toXXXOf
就会失效,有些居中操作也不好处理。他的不好地方可能是一开始不适应,而且会相对复杂,编写代码较多,但是适应之后就变得比较舒服与合适。
属性
定位属性
1 | layout_constraintLeft_toLeftOf |
他们的值假如是某一个同集控件的id
则是,他的某条边在某个id
控件某边,假如值是parent
则是他的某一条边对齐parent
。比如layout_constrainLeft_ToRightOf
则是我自己的左边在目标id
的右边,或者是parent
,需要注意的是需要连两位连续位置才可以定位一个控件,比如需要同时左上
或者坐下
或者右上
或者右下
等,假如是设置上下
或者是左右
是不行的。其中上面的start
等同于left
,end
等同于right
,可以以下表为准
居中
比如我组件需要在父组件中居中,那么应该是他的四条边对齐父组件,也就是top
,right
,left
,bottom
。假如是需要某个组价相当于某个组件居中,则他的top和bottom对应为需要对齐居中的top和bottom。假如我们需要把某个组件置于某两个组件的中间,则设置目标控件的left
为左右的right
,right
设置为右边的left
既可。
margin
支持我们常见的margin,但是支持的前提是我们设置了对应的layout_constraintXXX
,比如需要支持android:layout_marginLeft
,我们就需要给该控件设置layout_constrainLeft_XXX
才可以起效,也就是用那条边确定位置那条边的margin才会起效,该属性与RL布局一样。
1 | android:layout_marginStart |
关于Gone属性
假如我们相对于某一个控件进行定位,但是假如改控件gone
了而不是invisible
,这时候gone
控件的margin和宽度高度都未0了,变成了一个点,这时候约束还是起效的,但是我们的相对组件的位置会发生移动,需要注意,这个属性是设置给自己的,不是给gone
的控件的,当自己的约束控件gone
的时候才会起效。
1 | layout_goneMarginStart |
bias
该属性一般与居中的控件一起使用,比如我们需要某个属性在居中之后进行一些偏差,比如位于View的1/3位置的时候就会使用到该属性,该属性只有居中的时候才会有效,他的值是一个浮点数0-1
之间。有
1 | layout_constraintHorizontal_bias |
View的大小
自适应问题
我们除了常见的wrap_content
,match_parent
,xxdp
之外,还可以通过layout_constraintWidth_default
和layout_constraintHeight_default
进行设置宽度,该属性只有我们设置的宽度为0dp
时才会起效,他的取值有
1 | spread:占用所有的符合约束的控件,相当于match_parent,这时候可以设置所有的margin |
对于我们目标控件的内容需要处于两个控件之间而又不能超出的时候,除了上面设置为wrap
之外,我们还可以不用设置上面的属性直接使用layout_constrainedWidth/layout_constrainedHeight
为true
也是可以的,也就是我们不用layout_constraintWidth_default
和layout_constraintHeight_default
也能达到这样的效果的。
宽高比例
我们使用layout_constraintDimensionRatio
来实现宽高比例,实现他的前提是宽高至少必须其中一个为0dp
。他的值由两种写法
2:1
W,2:1
或者是H,2:1
,其中W
或者H
都可以小写
他的计算如下:- 使用第一种值形式,那么则是宽度:高度,无论是谁为
0dp
都一样 - 假如使用第二种值形式,会有两种情况
- 其中假如width为
0dp
的时候,则根据值的首字母确定,比如是w,x:y
则是宽度比:高度为x:y,假如是h,x:y
则是高度比宽度为x;y - 假如是高度为0dp,则是与上面相反的情况
- 其中假如width为
最大最小
1 | android:minWidth="" |
链
Chains
,控件在横轴或者是竖轴形成元约束的时候,他们就可以组成一个链式约束。这里的形成约束是指组件之间存在相互约束,比如我是你的left,同时他的right也是你这种情况。当出现这种情况的时候,我们可以使用layout_constraintHorizontal_chainStyle
或者layout_constraintVertical_chainStyle
来进行分配控件的大小,注意的是改字段是给链头控件,也就是第一个控件使用的。他的值由三种
spread
,均匀的分配在一条线上,但是控件不与两边接触,同时各自的间距相同spread_inside
,均匀分布在一条线上,而且两边的控件是接触边缘的,同时各自的间距相同packed
所有的元素挤在中间,可以通过上面的bis
再进行具体的偏移
假如我们还需要进一步的设置各个控件之间的大小关系,可以继续使用layout_constraintHorizontal_weight
或者是layout_constraintVertical_weight
,他与LinearLayout
的layout_weight
有些相似,不同点在于使用的时候,他只对宽度或者是高度为0dp
而且layout_constraintWidth_default
为spread
的控件生效
圆形布局
涉及到三个属性
layout_constraintCircle
圆心,相对控件的id值layout_constraintCircleRadius
半径layout_constraintCircleAngle
角度
他需要先定位,定位之后再相对于圆心进行相对应的偏移。
辅助组件
GuideLine
,他是一条不会绘制只是方便我们做控件的时候方便查看View之间的关系的一个组件,有以下特有属性
layout_constraintGuide_begin
与上/左的距离layout_constraintGuide_end
与下/右的距离layout_constraintGuide_percent
占据的百分比位置
以上使用一个即可使得辅助线定位准确,同时它使用android:orientation
来确认是横的还是竖直的
Group
他的作用在于可以同时控制多个View的显示行,不用我们一个一个View去控制,同时他的优先级是高于View自身设置的visibleFlag
的,而下层的Group优先级也大于上层的Group
,同时Group
不能对子Layout的里面的控件进行设置。他是通过constraint_referenced_ids
来设置一些列的View,他的值是一个各个控件的字符串。需要注意的是他的赋值是通过getIdentifier
来实现的,我们进行代码混淆之后,我们的控件的id的名称可能会改变,这时候我们需要注意在混淆文件配置一下这些id不要被混淆,或者是通过代码的setReferencedIds()
来设置
Placeholder
占位布局,它本身不绘制任何内容,但是他回使得目标控件gone掉而显示到自己这里,他的约束属性会起效而目标控件的属性会失效,目标控件将只有内容属性起作用。他是通过content
进行设置目标id的。
Barrier
他是一个虚拟的控件,可以指定多个目标控件,然后使得受到他约束的控件与对应多个目标控件形成start/left/right/top/bottom/end
的约束。
他的值由
barrierDirection
指定自己的约束方向constraint_referenced_ids
指定自己被约束的多个目标控件的id字符串barrierAllowsGoneWidgets
指定假如目标控件gone之后讲不会受到他约束的控件ids
例子
1 | <?xml version="1.0" encoding="utf-8"?> |