ConstraintLayout
public class ConstraintLayout
extendsViewGroup
java.lang.Object
? android.view.View
??? android.view.ViewGroup
????? android.support.constraint.ConstraintLayout
一個(gè)constraintlayout是ViewGroup允許你在一個(gè)靈活的位置和大小的部件。
注:constraintlayout可作為一個(gè)支持庫,你可以使用Android系統(tǒng)從API級(jí)別9(姜餅)。因此,我們計(jì)劃隨著時(shí)間的推移豐富其API和能力。這個(gè)文檔將反映變化。
目前有各種類型的約束(constraints),您可以使用:
- 相對(duì)定位
- 外邊距
- 中心定位
- 可見性行為
- 尺寸約束
- 鏈
- 虛擬助手對(duì)象
注意,在約束條件下不能有循環(huán)依賴關(guān)系。
還參見ConstraintLayout.LayoutParams的布局屬性
開發(fā)者指南
相對(duì)定位
相對(duì)定位是一個(gè)在constraintlayout創(chuàng)建布局的基本構(gòu)建塊。這些約束允許您將給定的控件與另一個(gè)相對(duì)應(yīng)。你可以在水平軸和垂直軸上約束控件:
- 水平軸:左(left),右(right),開始(start)和結(jié)束(end)邊
- 垂直軸:頂部(top)、底部(bottom)和文本基線(text baseline)
一般的概念是將一個(gè)控件的一個(gè)側(cè)面約束到另一個(gè)控件的另一側(cè)。
例如,為了將按鈕B放置到按鈕A的右邊(圖1):

你需要做:
<Button android:id="@+id/buttonA" ... />
<Button android:id="@+id/buttonB" ...
app:layout_constraintLeft_toRightOf="@+id/buttonA" />
這告訴系統(tǒng),我們希望按鈕B的左側(cè)被限制在按鈕A的右側(cè)。這樣的位置約束意味著系統(tǒng)將嘗試讓雙方共享相同的位置。

這里是可用約束的列表(圖2):
- 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
他們都需要一個(gè)參考ID到另一個(gè)控件,或母(將參考父容器,即constraintlayout):
<Button android:id="@+id/buttonB" ...
app:layout_constraintLeft_toLeftOf="parent" />
外邊距

如果邊的外邊距被設(shè)置,它們將被應(yīng)用到相應(yīng)的約束(如果它們存在)(圖3),執(zhí)行邊距作為目標(biāo)和源側(cè)之間的空間。通常的布局邊距屬性可以用于此效果:
- android:layout_marginStart
- android:layout_marginEnd
- android:layout_marginLeft
- android:layout_marginTop
- android:layout_marginRight
- android:layout_marginBottom
請(qǐng)注意,一個(gè)外邊距只能是正數(shù)或等于零,并用一個(gè)尺寸。
連接到已消失(GONE)的部件時(shí)的邊距
當(dāng)一個(gè)位置的約束目標(biāo)的可視性是View.GONE,你也可以表示不同的邊際值可使用以下屬性:
- layout_goneMarginStart
- layout_goneMarginEnd
- layout_goneMarginLeft
- layout_goneMarginTop
- layout_goneMarginRight
- layout_goneMarginBottom
中心定位與偏置
對(duì)constraintlayout有用的方面是如何處理“不可能”的約束。例如,如果我們有類似的東西:
<android.support.constraint.ConstraintLayout ...>
<Button android:id="@+id/button" ...
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent/>
</>
除非constraintlayout恰好有相同大小的按鈕,約束不能同時(shí)滿足(雙方不能在我們最需要他們)。

在這種情況下會(huì)發(fā)生的是,約束作用類似于相反的力拉部件相同(圖4),這樣的部件將最終集中在父容器。這將同樣適用于垂直約束。
偏置(Bias)
默認(rèn)情況下,當(dāng)遇到這樣的相反的約束是中心的小部件,但你可以調(diào)整定位偏袒一方在另一個(gè)使用偏置屬性:
- layout_constraintHorizontal_bias
- layout_constraintVertical_bias

例如,以下將使左側(cè)與30%的偏見,而不是默認(rèn)的50%,使左側(cè)將較短,與小部件傾斜更向左側(cè)(圖5):
<android.support.constraint.ConstraintLayout ...>
<Button android:id="@+id/button" ...
app:layout_constraintHorizontal_bias="0.3"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent/>
</>
使用偏置,您可以制作用戶界面,將更好地適應(yīng)屏幕大小的變化。
可見性行為
constraintlayout有特定的處理部件被標(biāo)記為View.GONE。
GONE屬性的控件,像往常一樣,消失的部件不會(huì)顯示出來,也不是布局本身的一部分(例如,如果標(biāo)記為GONE,它們的實(shí)際尺寸不會(huì)改變)。
但在布局計(jì)算方面,GONE屬性的控件仍然是其中的一部分,具有重要的區(qū)別:
- 在layout之后,他們的尺寸將被視為零(基本上,他們將被解析成一個(gè)點(diǎn))
- 如果它們對(duì)其他小部件有約束,它們?nèi)匀粫?huì)牽涉到,但任何邊距都等于零。

這種特定的行為允許建立布局,您可以暫時(shí)標(biāo)記控件屬性標(biāo)記為已經(jīng)GONE,而不破壞布局(圖6),這可能是特別有用的,當(dāng)做簡單的布局動(dòng)畫。
注意:所使用的邊距將是B在連接到A時(shí)定義的邊距(如圖6所示)。在某些情況下,這可能不是你想要的外邊距(一個(gè)有100dp外邊距到其容器的邊,B只有16dp到A,標(biāo)記A的屬性為GONE,B將會(huì)有16dp的外邊距到容器)。出于這個(gè)原因,您可以指定一個(gè)備用的外邊距值,當(dāng)連接到控件被標(biāo)記為已GONE時(shí)(請(qǐng)參閱上面關(guān)于丟失邊距屬性的部分)。
尺寸約束
在constraintlayout的最小尺寸
您可以定義自己的constraintlayout最小尺寸:
- android:minWidth 設(shè)置最小寬度的布局
- android:minHeight 設(shè)置布局的最小高度
那些最小的尺寸,將用于constraintlayout布局,當(dāng)其尺寸設(shè)置為wrap_content。
部件尺寸約束
該部件的尺寸可以通過設(shè)置指定:android:layout_width和android:layout_height屬性在3種不同的方式:
- 使用一個(gè)特定的尺寸(或字面意義的的值,如123dp或尺寸引用)
- 使用wrap_content,這將要求部件來計(jì)算自己的尺寸
- 使用0dp,這相當(dāng)于“MATCH_CONSTRAINT”

前兩個(gè)圖以類似的方式作為其他布局。最后一個(gè)將以這樣的方式調(diào)整小部件的大小,以匹配設(shè)置的約束(見圖7,(a)是wrap_content,(b)是0dp)。如果設(shè)置了外邊距,他們將在計(jì)算中考慮了(如圖7所示,(c)用了0dp)。
重要的是:match_parent不支持控件包含在一個(gè)constraintlayout,雖然類似的行為可以定義使用match_constraint與相應(yīng)的左(left)/右(right)和頂部(top)/底部(bottom)約束被設(shè)置為“parent”。
比率
您也可以定義一個(gè)尺寸的一個(gè)小部件作為一個(gè)比率的另一個(gè)。為了做到這一點(diǎn),你至少需要有一個(gè)約束的尺寸被設(shè)置為0dp(即match_constraint),并設(shè)置屬性layout_constraintDimentionRatio給定比例。例如:
<Button android:layout_width="wrap_content"
android:layout_height="0dp"
app:layout_constraintDimensionRatio="1:1" />
將設(shè)置按鈕的高度與它的寬度相同。
比率可以表示為:
- 浮點(diǎn)值,表示寬度和高度之間的比率
- 以"width:height"形式表示的比率
你也可以如果尺寸設(shè)置為 MATCH_CONSTRAINT利用率(0dp)。在這種情況下,系統(tǒng)設(shè)置最大尺寸滿足所有約束,并保持指定的縱橫比。根據(jù)另一個(gè)維度約束一個(gè)特定的邊。您可以預(yù)先追加W或H,以分別限制寬度或高度。例如,如果一個(gè)維度是由兩個(gè)屬性約束(例如:寬度為0dp并且在父布局居中)可以指明哪一屬性應(yīng)該被約束,加上字母W(用于約束寬度)或H(用于約束高度)的比率前面,用逗號(hào)隔開:
<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"/>
將設(shè)置按鈕的高度遵從的16:9比率,而按鈕的寬度將匹配parent的約束。
鏈
鏈提供組別一樣( group-like)行為,在單一坐標(biāo)軸(axis)(水平或垂直)。在其他坐標(biāo)軸(axis)可以單獨(dú)的約束。
創(chuàng)建一個(gè)鏈
一組控件被認(rèn)為是一個(gè)鏈,如果他們通過雙向連接連接在一起(見圖8,顯示一個(gè)最小的鏈,用兩個(gè)控件)。

鏈?zhǔn)?/strong>
鏈由鏈的第一個(gè)元素(鏈的“首”部)上的屬性控制:

首部是水平鏈最左邊的部件,垂直鏈的最頂部控件。
鏈的外邊距
如果在連接上指定了邊距,它們將被考慮在內(nèi)。在展開鏈的情況下,外邊距將被去除分配的空間。
鏈的樣式
當(dāng)設(shè)置該屬性layout_constraintHorizontal_chainStyle或layout_constraintVertical_chainStyle于鏈的第一個(gè)元素,外鏈的行為將按照指定的方式改變(默認(rèn)是chain_spread)。鏈行為的改變會(huì)按照特定的樣式(默認(rèn)是CHAIN_SPREAD)。
- CHAIN_SPREAD -- 元素將展開(默認(rèn)樣式)
- Weighted chain -- 在CHAIN_SPREAD模式,如果一些比重設(shè)置為MATCH_CONSTRAINT,他們將分割可用空間
- CHAIN_SPREAD_INSIDE -- 類似的,但鏈的端點(diǎn)不會(huì)展開
- CHAIN_PACKED -- 鏈的元素將被包裝在一起。孩子的水平或垂直偏置屬性會(huì)影響填充元素的定位
比重鏈
鏈的默認(rèn)行為是在可用空間中均勻地展開元素。如果一個(gè)或多個(gè)元素使用match_constraint,他們將使用可用的空空間(他們之間平分)。屬性layout_constraintHorizontal_weight和layout_constraintVertical_weight將控制空間如何將分布式應(yīng)用MATCH_CONSTRAINT元素之間。例如,在一個(gè)鏈中含有兩個(gè)元素使用了MATCH_CONSTRAINT,第一個(gè)元素使用比重為2,第二個(gè)使用了比重為1,第一個(gè)元素占用的空間是第二個(gè)元素的兩倍。
虛擬助手對(duì)象
除了內(nèi)在的能力詳細(xì)的以前,你還可以在ConstraintLayout使用特殊的輔助對(duì)象來幫你布置。
目前,指導(dǎo)(Guideline)對(duì)象允許你創(chuàng)建的水平和垂直方向的指引,定位相對(duì)于constraintlayout容器。
控件可以通過約束它們?nèi)ザㄎ贿@樣的指導(dǎo)。
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
相關(guān)閱讀更多精彩內(nèi)容
- Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
- 想看我更多文章:【張旭童的博客】http://www.itdecent.cn/p/9b6e12d8eea0 概述 ...
- 簡書MarkDown支持有點(diǎn)問題,請(qǐng)?zhí)D(zhuǎn)到我博客查看該篇博客:http://weiyf.cn/2017/03/10...
- ConstraintLayout-約束布局 ConstraintLayout是一個(gè)ViewGroup,允許你以一種...