ConstraintLayout 是什么
ConstraintLayout 是在2016年的 Google I/O 大會上推出的一種新型布局方式-約束布局术荤,它可以靈活的控制組件在布局中的位置和大小扒接,Google 為約束布局提供了配套的視圖編輯器翼岁,讓我們可以在可視化的界面中以拖拽的方式進(jìn)行布局锰霜。可以認(rèn)為 ConstraintLayout 是升級版本的 RelativeLayout伟骨,在相對布局的基礎(chǔ)上仔夺,增加了比例這一概念,在下面的代碼中將為大家詳細(xì)介紹這一概念南捂。
以下吴裤,我將會用 RL 表示RelativeLayout,CL 表示 ConstraintLayout溺健,LL 表示 LinearLayout
我的環(huán)境
- Android Studio 版本:2.3
- ConstraintLayout 版本:com.android.support.constraint:constraint-layout:1.0.2
ConstraintLayout XML 屬性
從 Android Studio 2.3 版本開始麦牺,我們創(chuàng)建新的布局會發(fā)現(xiàn),默認(rèn)的根布局已經(jīng)變成了 CL
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.xiezhen.practice.DefaultActivity">
</android.support.constraint.ConstraintLayout>
接下來矿瘦,將 CL 與 RL 的屬性進(jìn)行比較枕面,在了解了 CL 的基本屬性后,將為大家介紹視圖編輯器的中的各種操作缚去,我會選擇幾種特有的操作進(jìn)行講解,相似的操作琼开,大家可以自行練習(xí)
ConstraintLayout 和 RelativeLayout
--- | CL | RL |
---|---|---|
與目標(biāo)組件左對齊 | layout_constraintLeft_toLeftOf | layout_alignLeft |
在目標(biāo)組件的右邊 | layout_constraintLeft_toRightOf | layout_toRightOf |
與目標(biāo)組件右對齊 | layout_constraintRight_toRightOf | layout_alignRight |
在目標(biāo)組件的左邊 | layout_constraintRight_toLeftOf | layout_toLeftOf |
與目標(biāo)組件上對齊 | layout_constraintTop_toTopOf | layout_alignTop |
在目標(biāo)組件底部 | layout_constraintTop_toBottomOf | layout_below |
與目標(biāo)組件下對齊 | layout_constraintBottom_toBottomOf | layout_alignBottom |
在目標(biāo)組件的上部 | layout_constraintBottom_toTopOf | layout_above |
與目標(biāo)組件基線對齊 | layout_constraintBaseline_toBaselineOf | layout_alignBaseline |
如上表格所示易结,RL的屬性,CL都有柜候,只不過在屬性中多了 constraintXXX搞动,這個部分,這部分代表 View 的邊渣刷,表示View的上鹦肿,下,左辅柴,右或者基線箩溃,只不過在RL中這一部分省略掉了。
在RL中碌嘀,我們可以相對于父布局進(jìn)行布局涣旨,例如將一個按鈕與父布局的上邊和左邊對齊,XML 的布局代碼是這樣的:

在CL中是這樣的:

兩種方式呈現(xiàn)的結(jié)果都是一樣的:

ConstraintLayout 的比例
在 RelativeLayout 中股冗,我們可以使用以下三種屬性來指明組件在父布局中垂直居中霹陡,水平居中或者居中

在 CL 中是這么做的
水平居中,建立與父布局左邊和右邊的依賴

垂直居中止状,建立與父布局上邊和下邊的依賴

下面的代碼展示了一個居中的按鈕


現(xiàn)在來講點和 RL 不同的東西烹棉,目前為止我們展現(xiàn)的效果都是 RL 或者 LL 可以實現(xiàn)的,讓我們看看 CL 的這兩個屬性怯疤,這兩個屬性的取值范圍都是[0,1]
- layout_constraintHorizontal_bias
-
layout_constraintVertical_bias
其實從屬性名我們也可以猜出它的作用浆洗,可以認(rèn)為是在水平方向或者豎直方向上偏移的百分比,上圖展示的按鈕居中旅薄,是因為默認(rèn)的bias屬性值為0.5辅髓,下面我們改變這兩個屬性值泣崩,將橫向的 bias 改為0.9,垂直的 bias 改為 0.1洛口,效果如下:


ConstraintLayout 的尺寸
不同于其他組件矫付,CL 內(nèi) View 的 layout_height 和 layout_width 有以下三種取值方式
- 指定一個具體指
- 使用 WRAP_CONTENT
- 使用 0dp,等價于 MATCH_CONSTRAINT屬性
注意:沒有 MATCH_PARENT 屬性,我們要注意約束的概念 0dp 就代表我們的寬高將充滿約束第焰,而不是充滿父布局买优,舉個例子,我們將中間的 Button 的頂部與上方 Button 的底部約束挺举,將中間 Button 的底部與下方 Button 的頂約束杀赢,并且將高度設(shè)置為 0dp, 期待的表現(xiàn)是高度充滿整個約束湘纵,效果如下:


ConstraintLayout 的寬高比
以前我們經(jīng)常有需求脂崔,需要滿足一定寬高比的 ImageView ,CL 給我們提供了易用的屬性 layout_constraintDimentionRatio 我們只需要按照 width:height 的形式填寫屬性值就可以了梧喷,需要注意的是layout_height,layout_width 兩個屬性至少有一個屬性值為0dp砌左,如果兩個都是 0dp,則需要指定一個受限制的邊如下圖铺敌,"h,11:3",意味著高度受限汇歹,按照寬高比11:3的比例跟隨寬度進(jìn)行變化


ConstraintLayout chain
約束鏈,可以在垂直或者水平方向上提供群組行為偿凭,什么樣的約束可以構(gòu)成一條約束鏈产弹,View 之間相互約束就可以形成鏈,例如下圖展現(xiàn)一條最小的鏈弯囊,Button1 的底部和 Button2 的頂部相互約束


約束鏈的幾種形式
- spread:視圖均勻分布
- spread_inside :chains 中頭部和尾部的視圖將會將會貼在各自的約束上痰哨,其余視圖將會均勻分布
- spread_with_weight:在spread 或者 spread_inside 模式中,你可以像指定 LinearLayout 的 layout_weight 屬性一樣來設(shè)置 CL 的 layout_constraintVertical_weight 來達(dá)到和 LinearLayout weight的同樣的效果
- packed:將視圖打包在一起常挚,默認(rèn)居中作谭,我們可以通過改變 chains 的 bias屬性值,來調(diào)整整條鏈的偏移位置
chain奄毡,可以讓我們很輕松的完成線性布局可以完成的事情折欠,并且更方便特性更強大,盜用一張官網(wǎng)的圖幫助理解 chains style:

spread

spread_inside

spread_with_weight

packed

packed bias

GuideLine
可以認(rèn)為是輔助線吼过,作用如其名了锐秦,我們可以在容器的水平或者豎直方向插入一條輔助線,容器內(nèi)的 View 都可以和輔助線建立約束盗忱,這個特性非常好用酱床,我們先來看看 GuideLine 的幾個屬性
- layout_constraintGuide_begin 指定輔助線距離容器頂部或者左邊的距離
- layout_constraintGuide_end 指定輔助線距離容器底部或者右邊的距離
- layout_constraintGuide_percent 指定容器的寬或者高度的百分比
下面這個效果應(yīng)該很常見,在中間插入一條垂直方向的 GuideLine趟佃,然后分別在 parent 右側(cè)和 GuideLine扇谣,parent 左側(cè)和 GuideLine 之間建立約束:


一些補充
- Percent
- Group
- Barriers
Percent
百分比布局昧捷,我們可以很容易的在 CL 中使用百分比布局,代碼如下罐寨,將 layout_constraintHeight_default 設(shè)置為 percent 即采用百分比的方式布局靡挥,然后設(shè)置 layout_constraintHeight_percent 的屬性值,來改變垂直方向的百分比鸯绿,設(shè)置寬度百分比相同跋破。


Group
通過 constraint_referenced_ids 屬性來指定 Group 包裹的 View,對這些 View 提供統(tǒng)一的可見性設(shè)置瓶蝴,目前感覺比較雞肋毒返,本來我以為可以使用 Group 來提供背景色的設(shè)置,或者其他群組行為舷手,但是很可惜拧簸,目前提供的群組行為只有可見性而已


然后將 visibility 屬性設(shè)置為 Gone ,可以看見兩個 Button 的約束聚霜,變成了一條 Group 約束狡恬。

Barriers
Barriers 可以理解為,在一組視圖指定的邊上創(chuàng)建一條 GuideLine蝎宇。
- constraint_referenced_ids屬性,指定引用的視圖組
- barrierDirection屬性祷安,指定邊(Barriers 的方向)姥芥,有以下6種可選值 start,left,top,end,right,bottom。
如下圖所示汇鞭,有的時候我們可能會有類似的需求凉唐,左右兩部分,左側(cè)部分是 Title 和 Content霍骄,右側(cè)為圖像或者其他內(nèi)容台囱,如果采用 LL 和 RL 嵌套的方式,很容易解決读整,如果使用 CL 布局的話簿训,我們就需要使用 Barrier 這個新特性來進(jìn)行布局,在 Title 和 Content 指定為 Barrier 的引用試圖組米间,然后在組的右邊設(shè)置一條 Barrier强品,將圖片與Barrier建立約束即可,如果不采用 Barrier 屈糊,而是直接讓圖片與 Title 或者 Content 建立約束的榛,都有可能產(chǎn)生重疊的影響
采用 Barrier


不采用 Barrier


總結(jié)
CL 還是很容易上手的,提供的各種特性比較強大逻锐,本文雖然是采用的 XML 的形式來介紹夫晌,但其實 CL 用視圖編輯器雕薪,直接采用拖拽的方式更加的便捷,CL確實是減少了視圖層級晓淀,但是有沒有帶來效率上的提升所袁,就見仁見智了,到底在多復(fù)雜的布局情況下適合采用 CL 官方也沒有給出明確的說法要糊,在我測試的幾個布局中纲熏,CL 的性能都沒有超過 RL。另外 CL 畢竟發(fā)布只有一年锄俄,個人感覺還有很多特性不夠成熟局劲,例如 Group 的特性居然只能夠改變?nèi)航M可見性,Barrier的特性明明可以和 Group 結(jié)合到一起奶赠,我相信CL之后會原來越完善??鱼填。