一、簡介
**ConstraintLayout **中文叫約束布局,是谷歌最新推出的布局組件,經(jīng)過一年多的發(fā)展已經(jīng)發(fā)布了正式版。它是一用靈活的方式處理位置和大小的ViewGroup 組件。
優(yōu)點:
1、向前兼容性。作為獨立的support庫,可以使我們在最低API 9的版本上面使用。
2、功能多樣。支持各種位置展示、布局排列的效果,在后續(xù)介紹中會有詳細講解。
3、可視化操作。在Android Stuido 布局管理器中的“Design”面板可以很方便的拖拽控件,新增、刪除約束。
4、后續(xù)潛力。谷歌在官網(wǎng)明確指出會每隔一段時間不斷豐富它的api和功能,發(fā)展?jié)摿χ档闷诖?/p>
5、有效的降低UI層級。由于每個view都是相互約束的關(guān)系,層級大大降低了。
缺點:
1、使用復(fù)雜。約束布局中有大量可配置的屬性,且互相搭配會有不同的效果,上手難度較高。
二、功能
“約束布局”顧名思義通過約束來控制子view的位置和大小。
現(xiàn)階段你可以使用它如下不同種類的約束:
l Relative positioning 相對定位
相對定位的操作類似android系統(tǒng)自帶的“RelativeLayout”,支持一個view相對于其他view展示自己的位置。
目前支持的位置關(guān)系如圖所示

例如:現(xiàn)在需要一個B控件展示在A的右側(cè)


所有相對定位的種類如下所示
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
l Margins間距
1.間距
約束間距屬性如下
android:layout_marginStart
android:layout_marginEnd
android:layout_marginLeft
android:layout_marginTop
android:layout_marginRight
android:layout_marginBottom
注意:和默認的內(nèi)置布局間距可以設(shè)置為負數(shù)不同,約束布局的子view間距只能是大于等于0的值。
2.不可見間距
如果當前view依賴的其他view被設(shè)置成為了Gone,我們可以設(shè)置這種情況下的不同間距。
對應(yīng)的View不可見時間距種類如下
layout_goneMarginStart
layout_goneMarginEnd
layout_goneMarginLeft
layout_goneMarginTop
layout_goneMarginRight
layout_goneMarginBottom
例如:現(xiàn)在需要一個B控件展示在A的右側(cè),但是如果A沒數(shù)據(jù)不顯示的時候B取消左間距


l Centering positioning and bias中心定位和偏移量
1. 中心定位
約束布局可以完成看似不可能的布局約束
例如:如下所示


如上圖約束布局沒辦法同時滿足和父控件左對齊又和父控件右對齊,因此會強制平等的拉
當前的view,因此當前的view就實現(xiàn)了居中對齊,這種情況同樣適用于豎直的約束。
2. 偏移
默認的相對約束(見上個例子)是居中展示的,但是可以通過偏移屬性,設(shè)置居左或居右


設(shè)置了水平方向的偏移量,button就在從左邊原點向右30%偏移,這種情況同樣適用于豎直的約束。
l Circular positioning 圓形定位
你可以約束一個控件相對于另一個控件的中心點的距離和角度來展示view的位置。
設(shè)置種類如下
layout_constraintCircle
layout_constraintCircleRadius
layout_constraintCircleAngle


l Visibility behavior 可見式行為
約束布局對子view被設(shè)置為Gone的情況有自己特色的處理方式
通常的布局如果view被設(shè)置為Gone,那么它不會被顯示出來而且不再是布局的一部分。
但是作為一個重要的區(qū)別,約束布局在子view被設(shè)置為Gone以后依然被認為是布局中的一部分。
1.對于布局傳遞(layout pass),當前Gone view的尺寸被設(shè)置為0(通常這種情況被當做成一個點)
2.如果其他view依賴與當前Gone view的約束,那么這個Gone view依然會被作為一個已存在的view,只是它的間距全部為0



l Dimensions constraints 尺寸約束
1. 約束布局中的最小最大尺寸
設(shè)置種類如下
android:minWidth
android:minHeight
android:maxWidth
android:maxHeight
當前view尺寸被設(shè)置為WRAP_CONTENT的時候上面的設(shè)置會起作用
- 尺寸約束
android:layout_width 和 android:layout_height有如下的三種方式
a. 指定具體的值(比如設(shè)置為123dp或在dimens.xml定義的引用)
b. 使用WRAP_CONTENT,這樣當前view自己計算它的大小
c. 0dp,和MATCH_CONSTRAINT 效果一樣

前面兩種布局和其他布局效果是一樣的,但是MATCH_CONSTRAINT在約束布局里面會被重新調(diào)整大小。
(a)寬度為WRAP_CONTENT
(b)寬度為0dp
(c)寬度為0dp,并且有一個左邊的間距
注意:MATCH_PARENT在約束布局中不被推薦使用
3. WRAP_CONTENT強制約束
如果設(shè)置為設(shè)置為WRAP_CONTENT,但是實際長度超過了約束,可以通過如下設(shè)置來確定否強制約束
app:layout_constrainedWidth="true|false" app:layout_constrainedHeight="true|false"
- MATCH_CONSTRAINT尺寸
當一個view被設(shè)置為MATCH_CONSTRAINT時會把所有可用的空間都占用,這時使用android:minWidth 等屬性是不會起效的,但是可以用以下幾種屬性控制它
layout_constraintWidth_min
layout_constraintHeight_min
layout_constraintWidth_max
layout_constraintHeight_max
layout_constraintWidth_percent
layout_constraintHeight_percent
5. 百分比尺寸
為了使用百分比功能需要設(shè)置如下屬性
a. 尺寸必須設(shè)置為MATCH_CONSTRAINT
b. 默認的約束設(shè)置成百分比(1.1beta1或1.1bate2必須要,后續(xù)版本不需要)
layout_constraintWidth_default="percent"
或
layout_constraintHeight_default="percent"
c. 最后設(shè)置百分比屬性,值為0到1之間
layout_constraintWidth_percent layout_constraintHeight_percent
- 比率
可以設(shè)置一個view自己的寬高比,前提是寬和高有一個要設(shè)置為0dp。
例如:設(shè)置一個view寬和高一樣


比率可以是一個浮點類型的值,也可以是寬和高的比。
也可以同時設(shè)置寬高0dp ,系統(tǒng)會以最大尺寸滿足所有的約束條件,并維持寬高比。通過添加一個單獨的“H”或“W”來設(shè)置是通過寬還是高的比率來約束。


思考:上面的例子如果換成W,16:9會是什么效果?
l Chains 鏈
鏈提供了在單個軸(水平或豎直)上的一組行為的,另一個軸的行為
創(chuàng)造一個鏈
如果一系列的view彼此通過雙向關(guān)系連接在一起就被認為是一條鏈

鏈頭
鏈被第一個元素的屬性控制(鏈的頭)

橫向的鏈它的頭是左邊的第一個元素,豎向的鏈它的頭是頂部的第一個元素
鏈的間距
如果關(guān)系中指定間距,會根據(jù)情況來處理。比如“spread chains”,會被從可用的空間中去除
鏈的類型
在鏈頭添加layout_constraintHorizontal_chainStyle 或 layout_constraintVertical_chainStyle屬性,鏈的行為會被改變。
類型有如下幾種:
CHAIN_SPREAD -所有元素會被展開(默認情況)
WEIGHTED_CHAIN -在CHAIN_SPREAD 的模式下,如果一些view被設(shè)置為MATCH_CONSTRAINT,它們會被分開盡可能的位置。
CHAIN_SPREAD_INSIDE-類似CHAIN_SPREAD 模式,但是鏈的端點處的兩個view不會擴展。
CHAIN_PACKED-鏈的元素都會被擠滿,水平或豎直的比率(bias)屬性會影響包裹的元素的位置。

間距和鏈
鏈里面的元素它們的間距會被累加
例如,一個水平的鏈,一個元素定義了一個右間距10dp,下一個元素定義了一個左間距5dp,這兩個元素之間的間距就是15dp
虛擬的幫助對象
Guideline 對象允許你創(chuàng)建水平或豎直的指南,可以幫助view確定相對于約束布局內(nèi)的位置。
例如通過一個Guideline左邊約束Button定位在適當?shù)牡胤?/p>


部分圖片及參考資料來源:https://developer.android.com/reference/android/support/constraint/ConstraintLayout#CenteringPositioning