参考文章
- constrainlayout官方说明
- constrainlayout约束性布局指示梳理
- 约束布局constrainlayout看这一篇足够了
- 使用约束布局constrainlayout动态设计你的Android视图
- Android新特性:constrainlayout使用
constrainlayout是Android很早版本提供的一个布局view,针对嵌套多层的布局view可以很方便的通过约束实现单层布局(内质是viewgroup),类似于relativelayout但是优于relativelayout,最新版本新建布局文件默认rootview正是constrainlayout。解释说明上面大神都说的很明白了,我就不班门弄斧了,此处主要是做整理总结(更多是在我的使用过程中进行整理,方便后续自己查阅,也方便大家参考),下面总结是通过其属性分类进行整理的(在使用过程中持续更新)
- 相对布局(Relative position),理解相对布局需要优先理解三个名词:源控件,目标控件,父view,后面很容易理解,前面两个比如:a控件在b控件左面:a为目标控件,b为源控件。
* left/right,start/end区别:这四个属性都是控制view组件横向的,前面两个是固定绝对布局,后面两个是区分阅读方向的,后续Android系统支持阅读(适配地区阅读习惯)ltr/rtl,中国ltr阅读习惯,使用前面更好一些,后面有版本要求(api>=17)
* 相对布局属性是针对源控件和目标控件的,比如:app:layout_constraintLeft_toLeftOf:前面left是目标控件左侧,后面left是源控件的左侧,其他属性雷同
* app:layout_constraintBaseline_toBaselineOf:textview(文本控件)特有属性,textview存在基线对齐,此属性是定义两个textview基于基线对齐。
* 约束布局属性效果依赖于目标view的width和height的设置,具体可以参考下面的尺寸约束。 - 边距(margins)
* 约束布局的margins和普通view的margins属性设置保持一致,需要注意的是margins设置生效是基于上面的relative position设置的。
* 约束布局提供了view隐藏就不显示的margins,此种场景很常见的,比如a,b两个横向控件,a显示,b控件距a5dp,a隐藏,b控件取消间距,以前需要动态代码去处理,此时利用这个属性app:layout_goneMarginLeft(其他方向雷同),可以轻松实现。 - 可见性行为(Visible behavior)类似于view的INVISIBLE状态,view隐藏但是view的布局状态还存在,其他相对于此view的其他view margin,相对状态等还存在,这个牛逼的是,会将view浓缩成一个点,不让其占用布局。即可以实现view即gone掉,又可以保持其对应的约束条件不发生改变,约束条件存在在某些场景好用,两个居中变单个居中,在另外一些场景不好用即需要保留前面的view的布局大小的时候。
-
view相对于父view居中定位:
- 偏差(bias)
* bias是子view基于父view进行位置调控的,并不是两个或者多个子view进行位置调控,和linearlayout的weight还不太一样(理论上应该能够实现weight的效果)。
* bias既然是基于父view的,很明显bias属性也依赖于上面的居中定位属性(反向属性) - 圆形定位:以圆的角度进行布局控制,平时用到不多,不再整理
-
尺寸约束
* width/height设置为0dp后,通过下面的属性可以方便的控制其最小、最大宽高度。即:
* view设置为wrapcontent时候系统属性minwidth/maxheight等系统属性可以支持,早期版本可能依赖于下面的强制约束的属性,此处不太明白,还没有使用场景,待以后使用后重新整理,
* 控件尺寸约束即空间的width/height的设置存在下面三种状态:直接写死dp/wrapcontent(此状态上面的relative position可能存在问题,view自己计算width/height会占用本不属于他的布局)/0dp(相对于约束布局中的matchprarent,全部填充父布局)
* 针对上面提到的设置width为wrapcontent后,宽度的约束维度不起作用(实测view宽度会无视约束无限制的去绘制),设置下面两个属性可以强制当前view执行宽高度约束,即:app:layout_constrainedWidth=”true|false”【默认false】/app:layout_constrainedHeight=”true|false”【默认false】
* 针对上面提到知识点,view的宽高设置可以根据场景动态的设置具体/0dp/wrapcontent
* 上面提到的百分比比较特殊,即可以设置最小比例,还可以设置最大比例,不过都是相对于父布局来说的。 - 设置宽高比例(ratio)布局开发中很多场景都使用到宽高比例动态布局,以前的是实现是根据比例动态测绘view的宽高,使用这个属性不需要那么麻烦,即: app:layout_constraintDimensionRatio
* 使用这个属性设置宽高比:两种设置:一是浮点数另一个是比例值 - 链:链是作用于多个view的,可以实现类似于lianearlayout的weight的特性,不过这个属性实现的功能更强一些:
* 链头:当前父view的所有子view可以看做是一个链,其第一个子view为链头,属性也是设置给链头view,且链存在多个模式:平分布局(spread)/扩散对齐(spread_inside)/按比例分割(spread,但是借助其他属性)/连接居中对齐(packed)/连接居中对齐(带有偏移量,packed但是借助其他属性)
* 按比例分割/带有偏移量居中对齐两种设置都是在设置的基础上依赖其他属性,即:比例分割依赖于:app:layout_constraintHorizontal_weight/偏移量居中对齐依赖上面的偏移量属性 - 辅助布局:
* guideline:布局辅助线,不会再具体布局中显示,类似于一个标杆,在复杂布局中,多个view相对于父view布局比较麻烦的时候,可以横向/竖向画一条参考线,让布局view参考这个线进行布局,进而大大的简化了布局
* guideline相对于父view,具体定位通过下面三个属性定位:
barrier:对齐方式辅助类,通过属性app:barrierDirection="start"设置其前对齐还是后对齐,可以控制对个view空间对齐到一条线,表单文件常用
group:嵌套布局简化了布局嵌套,让复杂的布局都存在于一个层级中,很复杂的一个问题就是控制多个view显示还是隐藏,以前可以通过父布局很简单的控制,当前去掉了层级再通过父布局不容易控制通过group可以将子view进行打包处理,完整控制,存在两个问题:- group的优先级高于单个view,即group设置属性后group里面的单个view设置无效。
- group当前仅用于多view的显示和隐藏还有就是多view的z轴设置,其他的功能属性目前系统不支持。
placeholder约束布局中的占位辅助类,和普通布局中的ViewStub类似,需要的时候再初始化并设置到对应的位置
*辅助布局不是通过属性控制,都是类似于view的辅助类声明实现