Android ConstraintLayout 使用指南

技術視界發表於2017-04-16

升級Android Studio 2.3之後,IDE預設生成的Activity佈局都是以ConstraintLayout做為根佈局,體驗了一把這個Google去年就開始力推的ConstraintLayout後,覺得非常不錯,本文用於記錄ConstraintLayout各個方面的使用知識。

平臺支援

  • ConstraintLayout最低相容Android 2.3;
  • 目前Android Studio 2.3預設使用ConstraintLayout作為佈局檔案的根佈局;
  • 想要使用ConstraintLayout,需在專案的build.gradle新增com.android.support.constraint:constraint-layout:XXX版本號依賴;

基礎使用

ConstraintLayout翻譯成中文也稱為約束佈局,在整個使用體驗過程中真的是貫穿約束二字,這一節先來介紹一些基礎使用,後面你就會慢慢感受到約束佈局的魅力。建立完工程後開啟佈局檔案,底部切換Design的Tab上,可以看到整個操作介面

左上角的皮膚是放置了系統內建各種各樣的控制元件,想要佈局直接拖到到佈局檔案中即可(所見即所得),右邊的皮膚是選中佈局檔案中的控制元件時期各種各樣的空間屬性,ConstraintLayout最大的好處在於讓我們通過拖控制元件的形式進行佈局,並且不用擔心適配問題。所以,先來拖個控制元件試試看,將一個Button拖動到螢幕正中央,然後執行顯示看看效果。

模擬器執行後的效果

而實際執行後卻發現,這個Button還是位於螢幕左上角,說好的居中效果呢?這裡就要開始引入ConstraintLayout的約束概念,我們切換回去看xml的佈局程式碼,發現了兩個問題。第一,佈局預覽時能夠看到顯示居中的Button,是因為控制元件屬性設定中引用了兩個tools名稱空間下的屬性。

我們都知道,這兩個屬性只在佈局編輯器的預覽中有效,實際執行效果是不生效的。第二,Button標籤下有紅色波浪線警告,我們把滑鼠移到對應位置會發現警告內容,告訴我們Button沒有任何約束設定,當前效果只支援預覽,實際執行後會返回到左上角去,同時提示我們應該給控制元件新增約束。

如何增加約束?回到Design頁面,對著控制元件上下左右四個原點拖動新增對應的約束即可

成功新增約束後,即可得到正常的執行效果了。

實際操作不一定要在Tab,也可以直接在Text頁面拖動控制元件新增約束

成功實現新增約束後,可以看到Button多了下面幾個屬性設定

app:layout_constraintBottom_toBottomOf=”parent” 意思是Button底部的佈局約束是位於parent的底部,parent是指包裹著它的ConstraintLayout,也可以設定指定某個控制元件的id,其他類似的屬性就不再贅述,以上四個約束聯合起來便實現了Button的居中,ConstraintLayout總共有下面這些同類的屬性

你會發現ConstraintLayout非常靈活的把RelativeLayout的活給幹了,關於left、right、top、bottom、start、end、baseline的基準可以參照下圖

如果我想加多一個Button2並且將其放置到原先居中Button的右方並且與其底部對齊,只需如下操作即可

並且你也可以發現,Button2依賴與Button後會隨著Button的移動而跟著發生相對移動,目的是了保證我設定的依賴,時刻保持Button2就在Button的右邊,並且底部對齊。你也可以看到佈局檔案中也為Button2新增了如下兩個屬性

如果你已經理解上面提到的屬性含義,這裡應該不會有疑惑。

介紹完上下左右的依賴設定後,下面介紹一些Margin屬性,除了Android常見的各種android:layout_marginXXX外,ConstraintLayout自行新增了如下屬性

這些設定生效於當依賴的約束物件被設定visibility為gone時,非常簡單,讀者自行設定實踐對比即可,這裡就不展示效果了。

聊完Margin後,再來介紹一下Bias,ConstraintLayout新增瞭如下兩個屬性用於控制控制元件在水平和垂直方向在螢幕上的偏移比例

當為目標控制元件設定好橫縱向的約束時(app:layout_constraintLeft_toLeftOf=”parent”、app:layout_constraintRight_toRightOf=”parent”或者app:layout_constraintTop_toTopOf=”parent”、app:layout_constraintBottom_toBottomOf=”parent”),這個兩個屬性才會生效。實際操作過程中,你會發現對著設定好橫縱向約束的Button進行拖動,佈局中的layout_constraintHorizontal_bias和layout_constraintVertical_bias會一直髮生相應的變化,如果你需要Button居中,那麼直接將這兩個屬性的引數值設定為0.5即可。

關於ConstraintLayout的基本使用,這一節就介紹到這裡。

進階使用

看完基本使用,再來學習一些進階技巧,這裡先補充一個關於ConstraintLayout的知識點,與其他Layout不同之處在於,它的layout_width和layout_height不支援設定match_parent,其屬性取值只有以下三種情況:

  • wrap_content;
  • 指定具體dp值;
  • 0dp(match_constraint),代表填充約束之意,注意不要以為和match_parent是一樣的;

想想如果沒有ConstraintLayout,我們要讓一個控制元件的寬高按某個比例進行佈局應該怎麼做?有了ConstraintLayout後,我們可以使用layout_constraintDimentionRatio屬性設定寬高比例,前提是目標控制元件的layout_width和layout_height至少有一個設定為0dp,如下讓一個ImageView寬高按照2:1的比例顯示

layout_constraintDimentionRatio預設引數比例是指寬:高,變成高:寬可以設app:layout_constraintDimensionRatio=”H,2:1”。

ConstraintLayout的鏈條(Chains)特性非常強大,在沒有ConstraintLayout之前,線性佈局我們主要都依靠LinearLayout來完成,有了ConstraintLayout之後,它把LinearLayout的活也幹了,例如要把按鈕水平排成一行,可以這樣操作

這樣ButtonA、B、C就在水平方向形成了一條Chain,並且底部對齊。回去看xml檔案,會見到ButtonA新增app:layout_constraintHorizontal_chainStyle的屬性設定,這個屬性在一條Chain中只會出現在第一個控制元件中,這個控制元件是整條Chain的Head。

除了水平方向的layout_constraintHorizontal_chainStyle外還有垂直方向的layout_constraintVertical_chainStyle,兩者均有spread,spread_inside,packed這三種取值,如果將控制元件的layout_width和layout_height設定成為0dp,還可以配合layout_constraintHorizontal_weight、layout_constraintVertical_weight兩個屬性實現和LinearLayout中設定layout_weight相同的效果,具體的操作這裡就不再展示了,下面一張圖告訴你Chain的強大之處。

關於Chain的就介紹到此,進階的最後一部分再介紹一下Guideline功能,如果我們需要對著螢幕的中軸線進行佈局,就可以使用到Guideline進行操作,例如下面兩個Button分別分佈在中軸線的左右兩側

從操作上我們可以看到Guideline也分為垂直和水平兩種,並且支援設定在螢幕中所處的位置,可以使用layout_constraintGuide_begin和layout_constraintGuide_end設定具體dp值,也可以使用layout_constraintGuide_percent來設定比例。實際上它也只是一個輔助我們佈局的View而已,其原始碼內部實現也非常簡單,並且預設設定了visibility為gone,關於ConstraintLayout的進階使用便介紹到這裡。

使用優勢

關於ConstraintLayout的使用優勢,我個人體驗總結如下:

  • 高效佈局,Android這麼多年以來真正意義上的實現了所見即所得的拖曳方式佈局,極大的提高開發效率;
  • 輕鬆靈活的實現複雜的佈局;
  • 解決多重佈局巢狀問題,通過前面介紹你會發現ConstraintLayout真的是非常靈活,可以很大程度的避免Layout之間的巢狀;
  • 滿足螢幕適配的需求,想想沒有ConstraintLayout之前的拖曳式佈局,你就知道有多噁心;

最佳實踐

ConstraintLayout最開始出來就有很多開發者盼著完全依賴於拖曳方式實現佈局,而在實際操作過程中,完全通過拖曳其實效率反倒是會打折扣,在此建議是拖曳方式和xml編碼相結合才是最佳實踐的方式。

相關文章