Google曰:
ConstraintLayout 最出色之处是基于约束的布局系统,让您无需嵌套任何视图组即可构建大多数布局。
配置
-
Android Studio 需更新至version 2.3 or higher,才可以更好的体验ConstraintLayout带来的方便。
-
下载ConstrintLayout相关的SDK Tools:
- ConstraintLayout for Android
- Solver for ConstraintLayout
-
dependencies
//约束布局 compile 'com.android.support.constraint:constraint-layout:1.0.2'
使用简介
具体关于ConstraintLayout在AS工具中的使用技巧,下面的推荐博客中都有详细的图文视频介绍,这里我就不记录了,仅仅只是针对ConstraintLayout的属性做一下学习记录,以便加深对ConstraintLayout的理解
Relative positioning 相对位置(父子关系OR兄弟关系)
-
Horizontal Axis: Left, Right, Start and End sides
-
Vertical Axis: top, bottom sides and text baseline
//B的左边约束为居于A的右边。 <Button android:id="@+id/buttonA" ... /> <Button android:id="@+id/buttonB" ... app:layout_constraintLeft_toRightOf="@+id/buttonA" />
//居于ConstraintLayout的左边界(基于容器的位置) <Button android:id="@+id/buttonB" ... app:layout_constraintLeft_toLeftOf="parent" />
总得来说,layout表示控件布局位置属性,中部(constraintLeft)表示控件自身的哪一边的约束,后部(toRightOf)表示控件位置的最终决定者,类似于RelativeLayout中的属性
- layout_constraintLeft_toLeftOf
- layout_constraintLeft_toRightOf
- layout_constraintRight_toLeftOf
- layout_constraintRight_toRightOf
- layout_constraintTop_toTopOf
- layout_constraintTop_toBottomOf
- layout_constraintBottom_toTopOf
- layout_constraintBottom_toBottomOf
- layout_constraintBaseline_toBaselineOf
- layout_constraintStart_toEndOf
- layout_constraintStart_toStartOf
- layout_constraintEnd_toStartOf
- layout_constraintEnd_toEndOf
这些属性的命名空间需要自定义(默认app)
Margins
常规的margin属性是全部支持的,用法不变
- android:layout_marginStart
- android:layout_marginEnd
- android:layout_marginLeft
- android:layout_marginTop
- android:layout_marginRight
- android:layout_marginBottom
Margins when connected to a GONE widget
ConstraintLayout新增针对当前约束基于的Widget被GONE掉时的属性支持
- layout_goneMarginStart
- layout_goneMarginEnd
- layout_goneMarginLeft
- layout_goneMarginTop
- layout_goneMarginRight
- layout_goneMarginBottom
<TextView
android:id="@+id/tv1"
android:layout_width="wrap_content"
android:layout_height="20dp"
android:text="texxxxxxxxssssssssssss"
android:visibility="gone" />
<TextView
android:id="@+id/tv2"
android:layout_width="wrap_content"
android:layout_height="20dp"
android:text="texxxxxxxx"
app:layout_constraintTop_toBottomOf="@id/tv1"
android:layout_marginTop="60dp"
app:layout_goneMarginTop="25dp"
/>
上述代码中,tv2同时使用了layout_goneMarginTop与layout_marginTop,其作用场景是由tv1的状态决定的,tv2的当前约束是基于tv1的,当tv1为GONE时,layout_goneMarginTop设置的值起作用,当tv1为VISIBLE与INVISIBLE时,layout_marginTop的值起作用。
Centering positioning and bias 居中与偏移的处理
做居中处理(bias默认为0.5),或者根据bias值的不同控件的偏移位置不同
- layout_constraintHorizontal_bias
- layout_constraintVertical_bias
Dimensions constraints 尺寸约束
Minimum dimensions on ConstraintLayout
针对ConstraintLayout自身的属性,当ConstraintLayout被设置为WRAP_CONTENT时,设置的最小值限制会起作用
- android:minWidth
- android:minHeight
You can define minimum sizes for the ConstraintLayout itself.
Those minimum dimensions will be used by ConstraintLayout when its dimensions are set to WRAP_CONTENT.
Widgets dimension constraints
针对控件的尺寸约束有三种模式
-
固定值;
Using a specific dimension (either a literal value such as 123dp or a Dimension reference)
-
包裹内容:
Using WRAP_CONTENT, which will ask the widget to compute its own size
-
0dp,效果为:最大限制的往控件的左右OR上下约束进行延伸。
Using 0dp, which is the equivalent of "MATCH_CONSTRAINT"
具体实现可以观看郭神博客中的相关视频示例
Ratio 固定控件的宽高比
- layout_constraintDimentionRatio
使用前提是width、height至少有一个设置为0dp,使得控件拥有一个固定宽高比,以实现屏幕的自适应。
ratio值有两种写法:
-
一个float类型的数值,此值固定的代表W:H;
<Button android:layout_width="wrap_content" android:layout_height="0dp" app:layout_constraintDimensionRatio="1.78" />
a float value, representing a ratio between width and height
-
直接以比例的形式呈现的
<Button android:layout_width="wrap_content" android:layout_height="0dp" app:layout_constraintDimensionRatio="16:9" /> <Button android:layout_width="0dp" android:layout_height="0dp" app:layout_constraintDimensionRatio="H,16:9" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintTop_toTopOf="parent"/>
a ratio in the form "width:height"
指定比例时,可以事先指定需要约束的(H OR W);实际上当未指定时,默认下哪个是0dp就是约束的哪一个。
Chains 链条式排布
将多个View串联一排,View之间进行相互约束,类似链条一样相互锁扣。每个Chain的存在都有一个Chain Head,即Chain的第一个元素。
- layout_constraintHorizontal_chainStyle
- layout_constraintVertical_chainStyle
- layout_constraintHorizontal_weight
- layout_constraintVertical_weight
ChainStyle
官方提供三种样式
- spread (default style)
- spread_inside 空隙在内部
- packed View相互紧挨着,无空隙
非对称双View的同时居中
==利用packed ChainStyle可以实现类似LinearLayout的非对称双View居中问题==
<TextView
android:id="@+id/textView111"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintVertical_chainStyle="packed"
app:layout_constraintRight_toLeftOf="@+id/imageView111"
app:layout_constraintTop_toBottomOf="@id/ll_total_invest"
app:layout_constraintHorizontal_chainStyle="packed" />
<ImageView
android:id="@+id/imageView111"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="@id/textView111"
app:layout_constraintLeft_toRightOf="@id/textView111"
app:layout_constraintRight_toLeftOf="@id/guideline"
app:layout_constraintTop_toTopOf="@id/textView111"
app:srcCompat="@mipmap/ic_launcher" />
Weighted Chains
使用weight的前提是Chain中存在设置为MATCH_CONSTRAINT的View且chainStyle为spread系列,当有多个View设置了MATCH_CONSTRAINT,则weight就是用来在这个几个View之间分配剩余空间的。
Absolute positioning 绝对位置
- layout_editor_absoluteX
- layout_editor_absoluteY
基于容器ConstraintLayout的左上角为(0,0)
layout_constraint*_creator系列属性
- layout_constraintLeft_creator
- layout_constraintTop_creator
- layout_constraintRight_creator
- layout_constraintBottom_creator
- layout_constraintBaseline_creator
特征
- 这些属性都是基于tools的命名空间下的
- 经实践无论是否添加or删除这些属性,对View在布局中没任何影响
由于未找到相关的官方文档支持,具体作用无法确定,不过由上述两点,大概可以猜测,可能是基于Android Studio的一种辅助属性,类似tools:context=".*Ativity"的属性,与具体功能代码无关,只是一种辅助指引,或者方便开发者的
ConstraintLayout: What does layout_constraintLeft_creator
do in xml?
GuideLine
GuideLine是为了辅助ConstraintLayout实现更多的View约束而诞生的,只能与ConstraintLayout配合发挥作用。
GuideLine的实质就是一个被设置成View.GONE的View
- A Guideline can be either horizontal or vertical:
- Vertical Guidelines have a width of zero and the height of their ConstraintLayout parent
- Horizontal Guidelines have a height of zero and the width of their ConstraintLayout parent
Guideline在ConstraintLayout中作为别的View的一个参照物,以便更为灵活的布局,即使用中只需要控制好Guideline的位置即可。
三种设置位置的方式
-
layout_constraintGuide_begin
- 与ConstraintLayout起始位置的绝对距离
-
layout_constraintGuide_end
- 与ConstraintLayout结束位置的绝对距离
-
layout_constraintGuide_percent
- 占有ConstraintLayout width or height的百分比
orientation属性用来设置Guideline的方向,是横向参照物还是纵向参照物
ConstraintLayout总结
ConstraintLayout基本上实现了LinearLayout、RelativeLayout、PercentLayout的所有功能,并且还拥有这三者所不具备的新功能
优点
- 只需一个ConstraintLayout做为根布局,所有子View都是其一级子View,解决了复杂布局的嵌套问题
- 利用左右或者上下两个guideline 可以实现百分比布局的效果;
- 如果再加上ratio的使用更是在百分比布局的基础上可以实现View固定的屏占比与宽高比;
- 通过设置width的屏占比与宽高比,变相的实现了height在横向上的屏占比,而这又是PercentLayout所不能实现的功能;
- 通过layout_goneMarginXXX系列属性,可以使得我们实现更为智能灵活的布局效果
- 关于性能方面,官方及其开发者都是声称性能上要比RelativeLayout要好,至少实现同样的布局,不比RelativeLayout性能差,甚至要快一些。(说的是未来的性能吧【捂脸】)
PS:期待弹性布局FlexboxLayout 1.0的发布,有这两个布局,以前需要自定义Layout或者各种布局嵌套来实现的样式,都可以使用这个两个布局来轻松实现
缺点
- XML布局中的属性代码太多,会使得XML资源本身的大小增加;
- 经测试,ConstraintLayout在第一次初始化创建View的过程中,会比RelativeLayout与LinearLayout相互嵌套的实现的布局的初始化,要相对耗时一些;
ConstraintSet
用以代码中控制约束
推荐阅读
- 郭神博客 Android新特性介绍,ConstraintLayout完全解析
- Google官方教程 使用 Constraint Layout 构建自适应 UI (Build a Responsive UI with ConstraintLayout)
- Google官方文档 ConstraintLayout
- Google中国 使用布局编辑器构建 UI
网友评论