这里也包括一些老特性,源自官方文档。自己写了Demo进行整理
MATCH_CONSTRAINT
其实就是0dp,在这个模式下宽高都是由约束决定的。可以设置约束计算后的最小或者最大宽高,有四个xml属性:
- layout_constraintWidth_min
- layout_constraintHeight_min
- layout_constraintWidth_max
- layout_constraintHeight_max
可以设置约束计算后的百分比宽高,这里的百分比相对于父布局 - layout_constraintWidth_percent
- layout_constraintHeight_percent
layout_constraintWidth_min这类属性可以指定为dp,也可以写成wrap,这将会和wrap_content有相同作用
ConstraintSet
定义一组约束(下称约束集),定义时有如下特性:
- 指定约束集的约束布局中的所有子控件都要有id,不然会崩,提示你有控件没有指定id
- 如果要从约束集1切换到约束集2,那么约束集1中id和约束集2中id相同的控件的约束属性会变成约束集2中定义的
- 如果约束集1和约束集2中有不相同的控件id,那么在切换时只在对应(有那个控件id)的约束集中生效
例如:约束集1中有id为tv1,然后btn1的左边依赖tv1的左边,而约束集2没有tv1,那么切换到约束集2时btn1的lefttoleft就会置为unset(就相当于没有设置左对左约束)。如果约束集2有tv1或者btn1的左侧依赖tv2的左侧,相对位置依赖tv1的约束(lefttoleft)就会被覆盖 - 切换约束集时当前布局的所有控件id不变,仅仅将另一个约束集的约束规则应用到当前约束布局上。也就是说只改变位置,大小等,View的对象是没有变的,之前设置过得ClickListener都依然生效
相关语法: - 创建:clone()
- 通过xml布局创建:mConstraintSet2.clone(context, R.layout.layout_constraint_set2)
- 通过约束布局对象创建:mConstraintSet1.clone(mConstraintLayout)
- 切换约束集:applyTo()
- mConstraintSet1.applyTo(mConstraintLayout)
- 在xml中引用约束集:app:constraintSet="@layout/layout_con_set3"
- 有时候界面中控件的id是相同的,这时候可以直接引用另一个ConstraintLayout为根标签的XML的约束,这样就不用写重复的约束了
- app:constraintSet这个属性需要在ConstraintLayout标签上写,不能在子控件中写
- 代码中动态修改约束集中的约束:通过获取ConstraintSet的对象,可以在代码中动态改变约束属性。这样就不用像RelativeLayout一样通过LayoutParam进行修改了。操作方式类似于BRVAH框架的BaseViewHolder,都是给一个id然后给一些属性。
Group
通过id引用当前约束布局中的空间,然后统一控制这些控件的visiblity属性。本身也是一个View,但不可见,属于界面控制型View。通过设置这个View引用的setVisibility方法也可以更改组中的控件的显示和隐藏。引用id的写法为app:constraint_referenced_ids="button4,button9"
Guideline
这个View在1.0就有。但1.0的时候我没有看过这个View,所以这里也整理进来了。这个View是没有任何展示效果的,只是用来定义一个水平或竖直方向上的位置,然后让其他View
- 方向:
- Vertical:会在预览页面展示位一个竖直的虚线,宽为0,高为父布局
- Horizontal:水平虚线
- 位置:
- layout_constraintGuide_begin:如果是Vertical就是相对于父布局左边框的距离,如果是Horizontal就是相对于父布局上边框的距离,下同
- layout_constraintGuide_end
- layout_constraintGuide_percent:比如0.1就是到结束边的距离是到开始边的距离的9倍
- 代码中动态设置位置:
- setGuidelineBegin(int margin)
- setGuidelineEnd(int margin)
- setGuidelinePercent(float ratio)
Barrier(屏障)
这个约束控件和Guideline作用是很相似的也是一条线,但Guideline是“封建”的,而Barrier是“民主”的。Guideline生来就有位置,然后别的控件照着它的位置部署位置。Barrier的位置由它所引用的控件决定,然后再让其他控件根据他的位置来改变位置。
主要有三个属性:
- app:constraint_referenced_ids:它遵从的控件id集合,如:"btn1,btn2",就指示这个屏障是在哪组控件的最边缘
- app:barrierAllowsGoneWidgets:是否听从引用控件中GONE掉的控件。
- 默认为true,这样即使引用控件gone掉还是能影响Barrier的位置
- app:barrierDirection:枚举,一共六个。上下左右和start与end。
- 比如指定为 right:表示Barrier的位置是所引用控件集合最右边,并且间接指定了barrier是竖直状态的
Placeholder
本身也是一个View,默认情况下处于INVISIVBLE状态。它的作用就是指示一个指定位置(或者说一套约束),后续可能有View会移动到它的位置(将约束变成Placeholder的约束)。这个View在XML中的写法和最普通的View是一样的只是默认不显示出来。
- 当它的对象调用setContentId(int idRes)时就会将指定id的View的约束改成这个placeholder对象的约束,然后这个placeholder对象的尺寸会变成指定id的View的尺寸
- setContentId()调用之后就会变成VISIBLE状态,但会被content控件遮盖住
- 当setContentId(-1)时会恢复原来尺寸,即变为Empty状态,此时的显示方式由setEmptyVisibility设置过得属性决定
- 通过设置setEmptyVisibility()来控制没有content控件时的可见状态
测试Demo链接:https://github.com/z2058550226/ConstraintLayoutDemo
网友评论