ConstraintLayout 出来蛮久了,但是一直没怎么用,说是可以直接进行拖拽来实现布局,但是 xml 里全是写死的 dp,不实用。然后用代码吧,属性都贼长贼多,有些难记。最近同学强力安利,说多写写就熟悉了,于是项目新的布局基本都用 ConstraintLayout 来写了,刚开始写的时候确实比较慢,很多属性不知道,有些属性有什么用也不晓得,但是用了几天后,发现真好用!人类的本质啊,真香怪!
基本属性
- layout_constraintRight_toLeftOf
- layout_constraintRight_toRightOf
- layout_constraintLeft_toLeftOf
- layout_constraintLeft_toRightOf
- layout_constraintTop_toTopOf
- layout_constraintTop_toBottomOf
- layout_constraintBottom_toTopOf
- layout_constraintBottom_toBottomOf
- layout_constraintBaseline_toBaselineOf
见名思意,都很直接明了,还是很方便使用的。和 RelativeLayout 很相似,但是还有着 LinearLayout 的特性,可以说是结合了两大布局的特性,用起来爽歪歪。用这些基础属性已经可以实现大部分的布局了,而且布局嵌套层级就一级。举个例子:
1 | <android.support.constraint.ConstraintLayout |
界面效果如下:
goneMargin
如上图的界面中,为了加大「目录」两字的点击相应区域,给它设置了左右 16dp 的 padding,但是某些情况下,这个「目录」不需要展示,设置为 GONE 之后「关注」按钮距离右边的距离就只剩 4dp 了,需要手动改为 16dp,这样就得写一句很蛋疼的代码:
1 | (followTv.layoutParams as ViewGroup.MarginLayoutParams).rightMargin = DimenUtils.dp2px(16F) |
但是利用 ConstraintLayout 之后,你会发现一句 xml 代码即可搞定,给「关注」设置如下属性
1 | app:layout_goneMarginRight="16dp" |
当它依赖的 View 变为 GONE 时,仍然能保留 margin,ConstraintLayout 流弊!
chainStyle
上述代码中有一个属性:
1 | app:layout_constraintVertical_chainStyle="packed" |
可以将约束元素组成一个链,chainStyle 用来设置元素之间的效果。
weight
经常有这种布局:
1 | <LinearLayout |
ConstraintLayout 利用 layout_constraintHorizontal_weight 或 layout_constraintVertical_weight 也可以轻而易举的实现。只有一个 View 占据宽度的 1/3,利用 LinearLayout 可以将 View 换成 Space:
1 | <LinearLayout |
利用 ConstraintLayout 实现将会更简单:
1 | <android.support.constraint.ConstraintLayout |
忽略除不断的小数- -。
Group
经常会有这种需求:在某个场景下,展示哪些 View,在其他场景要隐藏这些 View,它们是同显示同隐藏的,一个两个 View 还好,如果 View 很多,写起来就很蛋疼了。用 Group 则会很简单。
1 | <android.support.constraint.Group |
然后使用 group.visibility 即可设置 ids 里面所有 id 对应的 View 了。
注:Group 只有在 1.1 及以上的版本才添加进来。
再注:Group 添加后的 id 再针对子 View 单独操作 visibility 是无效的。
代码:
1 | public void updatePreLayout(ConstraintLayout container) { |
界面绘制时,Group 关联的所有 View 的 visibility 只会根据 Group 来,要么全看得见,要么全看不见。
constrainedWidth
先看两张图:
文章 RecyclerView 处于微信图标的左侧,且从右边开始布局,嵌套布局很容易实现,看下约束布局如何实现:
1 | <android.support.constraint.ConstraintLayout |
将控件的尺寸设置为 wrap_content,那么对控件设置的 maxWidth、minHeight 这些约束是不起作用的,而强制约束就用于使控件在设置 wrap_content 的情况下约束依然生效。
小结
ConstraintLayout 还有很多我没用到特性,目前为止,我:真香!已经不想再用原始的三大布局了,嘿嘿嘿。