使用ConstraintLayout(約束布局)構建響應式UI
ConstraintLayout
(約束布局)是Google IO 2016推出的Android新布局方式。
以下內容翻自官方文檔。
ConstraintLayout
允許您使用扁平的層級(不用嵌套View Group)創建大型復雜的布局。與 RelativeLayout
類似,它通過相鄰的view和父layout的相對關系來確定位置,但比 RelativeLayout
更加靈活,更容易通過Android Studio的布局編輯器實現想要的效果。
ConstraintLayout
的所有功能都可以直接通過 Layout Editor
可視化工具實現,因為布局API和Layout Editor互相做了特別優化。所以您 只需要拖放布不必編寫一行代碼構建ConstraintLayout布局。
圖1.
Layout Editor
編輯 ConstraintLayout
ConstraintLayout的Api庫兼容 Android 2.3 (API level 9)或更高版本,新的Layout Editor需要Android Studio 2.2或更高版本
本文提供了在Android Studio中使用ContraintLayout構建布局的向導,如果您對Layout Editor更興趣,參見 Build a UI with Layout Editor.
約束概覽
在 ConstraintLayout
中定義一個view的位置,您必須為這個view添加至少兩條約束。每個約束代表與另一個view、父layout,或不可見的向導線的連系或對齊。每個約束沿着水平或垂直坐標定義了view的位置,所以每個view必須在每個軸上有一個最小約束,但通常需要多個。
當您把一個view拖進Layout Editor時,即便沒有約束,它也會留在你釋放時的位置。然而,這僅僅是讓您更容易編輯,如果一個view沒有約束,當您在設備中運行時,它始終會在左上角顯示。
在圖2中,布局在編輯器中看起來很好,但 TextView B
沒有垂直約束。當這個布局在設備中運行時, TextView B
會與ImageView的左右邊緣水平對齊,但出現在屏幕的最頂部,因為它沒有垂直約束.
圖2: TextView B缺少垂直約束
圖3:TextView B現在相對ImageView水平垂直約束
盡管缺少約束不會導致編譯錯誤,Layout Editor還是會在工具欄上將缺少約束顯示為錯誤。

查看錯誤和其他警告,點擊錯誤數字圖標。為了幫您避免缺少約束,Layout Editor可以使用Autoconnect和infer constraints 特性,幫您自動添加約束。
為您的項目添加ConstraintLayout
要在項目中使用 ConstraintLayout
,跟隨以下步驟:
1.確保您有最新的約束布局庫:
– 點擊 Tools
> Android
> SDK Manager
.
– 點擊 SDK Tools
選項卡
– 展開 Support Repository
,勾選 ConstraintLayout for Android
和 Solver for ConstraintLayout
,勾選 Show Package Details
,記住您下載的版本(下面會用到)
OK
– 在module級別(默認app)的build.gradle里添加ConstraintLayout庫依賴
dependencies { compile 'com.android.support.constraint:constraint-layout:1.0.0-beta4' }
您下載的版本可能更高,所以確保版本號與下載的匹配.
- 在工具欄或同步通知里,點擊
Sync Project with Gradle Files
現在,您已經准備好使用 ConstraintLayout
構建布局了
轉換布局
轉換現有布局到ConstraintLayout,跟隨以下步驟:
1. 在Android Studio中打開layout,在編輯器的底部,點擊Design標簽,
2. 在Component Tree窗口,右擊layout,點擊Convert layout to ConstraintLayout

圖4:轉換布局菜單
創建新布局
創建一個新的ConstraintLayut,跟隨以下步驟:
1. 在 Project
窗口任意處點擊,選擇 File
> New
> XML
> Layout XML
.
2. 輸入layout文件名, android.support.constraint.ConstraintLayout
作為Root Tag
3. 點擊 Finish
添加約束
從 Palette
拖動一個view到編輯器里開始。當您添加一個view到 ConstraintLayout
里時,它展示成一個包圍的盒子,四角帶方形大小調整把手,四邊的中間帶圓形約束把手。
點擊View選中它,點擊並拖住一個約束把手,拖動到可用的錨點上(另一個view、layout、引導線的邊緣),當您釋放時,約束就生成了,兩個view間帶一個默認的margin值
創建約束時,記住以下准則:
- 每個view至少有兩個約束,一個水平,一個垂直
- 同一平面上,您可以只在一個約束把手和一個錨點間創建約束。所以一個view的垂直平面(左右邊) 可以只被另一個垂直平面約束;基線可以只被其他基線約束
- 每個約束把手只能創建一個約束,但是同一個錨點上可以創建多個約束(不同的view)
如果要刪除約束,選中view,點擊約束把手
當您添加了相反的約束時,約束線會變成彎彎曲曲的彈簧狀。

這個效果當view的size設置成 fixed
或 wrap_content
時最明顯,它會讓view展示在約束的中間,如果您希望view擴展它的尺寸到約束上,,或者如果您 想保持當前大小,但是移動view,以便它不居中,可以
有很多方法可以限制一個視圖,但是下面的約束類型提供的基本構建塊。
父級約束
連接view的一邊到相應的layout邊緣,在圖5中,view的左邊緣連到了父級的左邊緣。

圖5 相對父級的水平約束
位置約束
為兩個view水平或垂直方向定義外觀規則。圖6中,一個 Button
被約束在一個 ImageView
下面,間隔24dp

圖6 垂直位置約束
對齊約束
一個view的邊緣與另一個view的同一邊緣對齊
圖7中, Button
的左邊緣與ImageView的左邊緣對齊
您可以通過向內拖動view調整對齊(增加margin,不支持向外拖,即margin不能為負值)
圖7 水平對齊約束
圖8 水平對齊約束 offset
基線對齊約束
對齊一個view的文本基線到另一個view的文本基線。
圖9中, TextView
的第一行與 Button
的文本對齊
創建一個基線約束,您可以選中view,點擊B,基線就會顯示,鼠標拖到另一個view的基線上即可(原文描述有點不一樣,可能是Android Studio老版本)
與引導線約束
您可以添加水平或垂直的引導線,基於它創建約束。您可以在layout內部用dp單位或者百分比放置引導線,相對layout邊緣。
創建引導線:點擊工具欄上的 Guidelines
圖標,選擇 Add Vertical Guideline
或 Add Horizontal Guideline
點擊引導線頂部的小圓點,切換百分比以及相對邊緣(上下,或左右)
引導線對用戶不可見
使用Autoconnect和Infer Constraints
Autoconnect
會為您添加到layout里的每一個view創建兩個或更多約束。 Autoconnect
默認關閉,您可以點擊 Layout Editor
工具欄上的 Turn on Autoconnect
圖標開啟。
當開啟后, Autoconnect
會在您添加view后創建約束,它不會為已經存在的view(開啟前添加)創建約束。如果您在約束創建后拖動view,約束不會改變(雖然margin會),所以如果您要大幅度改變view位置,您必須刪除約束。
作為另一種選擇,您也可以點擊 Infer Constraints
來為layout里的所有view創建約束.
Infer Constraints
(推斷約束)是一次性的動作,它通過掃描整個layout來推斷所有view的最有效設置,所以它可能會為兩個很遠的view創建約束。 Autoconnect
只與最近的元素創建約束。這兩種情況下,你都可以通過點擊約束把手刪除約束,創建新的約束.
調整視圖大小
您可以使用view每個角上的把手調整大小,但這么做會硬編碼(Hard codes)寬和高,這是您應該避免的,因為硬編碼無法適配不同的內容的屏幕尺寸。要選擇不同的動態尺寸模式,或定義指定大小,點擊view,打開編輯器右邊的屬性窗口,在窗口的頂部是視圖查看器,如圖10。
圖10 屬性窗口,包含視圖尺寸(1),邊距(2),約束偏移(3)
灰色的區域展示了選中的view,距形內的符號展示了寬高設置:
Wrap Content View會根據內容的需要自動展開
Any Size View會自動展開來匹配約束。實際值是0dp,因為view沒有期望的尺寸,但它會為匹配約束重置大小。然而,如果給定的尺寸只有一個約束,視圖會擴展以適應內容。對此的另一種理解是
match constraints
(而不是match_parent
),因為它在計算約束和邊距的限制后,盡可能多地展開視圖。Fixed 您在編輯器里通過調整view大小,在下面的文本框里指定了尺寸
要在這幾種模式間切換,在上面的圖形上單擊。
==注意:您不應該在ConstraintLayout上使用 match_parent
,用 Any Size
0dp 代替==
調整約束偏移
當您給一個view的兩邊都添加了約束(並且view的尺寸是都是fixed或者wrap content),默認情況下,view會在兩個錨點間居中。當一個view居中時,偏移是50%.您可以通過拖動屬性窗口中的偏移滑動條或拖動view來調整。
如果您想要view擴展它的尺寸到匹配約束,
調整view間距
確保您的view間隔均勻,點擊工具欄上的Margin 8
,為您添加的每個view選擇默認的間距。這個按鈕會展示您當前的默認間距設置。任何對默認間距的修改,僅對修改后新增的約束生效。
您可以通過屬性窗口單獨修改每個view的間距,(在圖10中,邊距被設為16dp).
工具中提供的所有邊距都是8的倍數,以幫助您的view符合Material Design的 8dp square grid recommendations
© 2017, 冰凍魚. 請尊重作者勞動成果,復制轉載保留本站鏈接!應用開發筆記