升級Android studio到2.3版本之后,發(fā)現(xiàn)新建Activity或fragment時(shí)盯捌,xml布局默認(rèn)布局由RelativeLayout更改為ConstraintLayout了纤壁,既然已經(jīng)推薦使用ConstraintLayout,學(xué)會(huì)如何使用就很有必要了轿亮。本文的主要是目標(biāo)是:圖文結(jié)合空凸,講講如何使用ConstraintLayout避矢。
引入ConstraintLayout###
為了使用ConstraintLayout,需要在app/build.gradle文件中添加相應(yīng)依賴:
dependencies {
compile 'com.android.support.constraint:constraint-layout:1.0.1'
}
此前ConstraintLayout依賴庫版本號都帶有beta字眼,現(xiàn)在已經(jīng)推出正式版本1.0.1龟再。當(dāng)然使用AS新建activity時(shí)书闸,AS會(huì)自動(dòng)添加這行依賴的。
創(chuàng)建ConstraintLayout###
新建ConstraintLayout布局文件后吸申,打開如圖所示:

雖然ConstraintLayout和RelativeLayout等都是ViewGroup的子類梗劫,但RelativeLayout,FrameLayout等是位于widget包下的享甸,ConstraintLayout則是在Support包下的截碴。點(diǎn)擊界面左下角的“Design”和“Text”可以切換顯示視圖,“Design”視圖是可視化視圖蛉威,提供拖拽等功能實(shí)現(xiàn)界面布局日丹;“Text”視圖是通過編寫xml代碼實(shí)現(xiàn)界面布局。

對于傳統(tǒng)布局蚯嫌,大部分開發(fā)者都是通過編寫xml代碼來現(xiàn)實(shí)布局的哲虾,顯得“Design”這個(gè)可視化工具相當(dāng)?shù)碾u肋。但對于ConstraintLayout來說择示,卻很適合使用這個(gè)可視化工具來實(shí)現(xiàn)布局束凑,今天將使用“Design”視圖來說明ConstraintLayout的使用。先來觀察“Design”視圖栅盲,

左側(cè)區(qū)域是預(yù)設(shè)的控件集合汪诉,頂部區(qū)域是操作欄位,右側(cè)區(qū)域則是預(yù)覽作用谈秫。
基本操作###
界面轉(zhuǎn)換####
如果布局不是ConstraintLayout,可以通過下圖操作進(jìn)行轉(zhuǎn)換:

如果轉(zhuǎn)換前的界面是嵌套的扒寄,你可以選擇一層一層轉(zhuǎn)換,也可以選擇在根目錄轉(zhuǎn)換拟烫。使用的時(shí)候该编,發(fā)現(xiàn)這個(gè)轉(zhuǎn)換功能并不是很強(qiáng)大,不能確保轉(zhuǎn)換后界面保持一致硕淑。
添加控件####
如果想添加一個(gè)Button课竣,只需從左側(cè)的Palette區(qū)域拖拽到預(yù)覽區(qū)域就可以了嘉赎。拖拽完成后,會(huì)在布局中自動(dòng)生成相應(yīng)的xml代碼稠氮〔芾“Design”工具是通過自動(dòng)生成代碼來實(shí)現(xiàn)布局的,本質(zhì)上還是通過xml實(shí)現(xiàn)布局隔披。兩者是相互聯(lián)系的赃份,其中一個(gè)發(fā)生改變,另一個(gè)會(huì)對應(yīng)改變奢米。下圖抓韩,添加一個(gè)Button:

通過拖拽,現(xiàn)在已經(jīng)添加了一個(gè)Button鬓长≮怂可以在“Text”視圖中看到,自動(dòng)生成了xml代碼涉波。雖然添加了Button英上,但由于還沒有給這個(gè)Button添加約束,所以在“Text”視圖下啤覆,可以看到Android Studio報(bào)錯(cuò)了:沒有為view添加約束苍日,但依然允許運(yùn)行。由于沒有約束窗声,Button并不知道自己所處的位置相恃,實(shí)際運(yùn)行效果和預(yù)覽效果是不一樣的,Button會(huì)出現(xiàn)在左上角笨觅。如果拖拽Button后拦耐,發(fā)現(xiàn)Button已經(jīng)有約束,那么肯定是打開了AutoConnect開關(guān)见剩,這個(gè)下文再詳說杀糯。
添加約束####
選中Button,能在上下左右看到四個(gè)空心小圓圈苍苞,把鼠標(biāo)移動(dòng)到小圓圈上固翰,小圓圈會(huì)變成綠色。這四個(gè)小圓圈就是用來給Button添加約束的柒啤,實(shí)際上所有控件view都有這樣的4個(gè)小圓圈【牍遥現(xiàn)在給Button左邊和右邊各添加一個(gè)約束,如下圖所示:

只需選中小圓圈然后拖動(dòng)鼠標(biāo)到父布局邊框即可成功添加約束担巩。上圖中方援,左側(cè)的預(yù)覽圖叫“Design”,右側(cè)藍(lán)色的視圖叫“Blueprint”,添加約束的操作在任意一個(gè)視圖上都可以完成涛癌。
上面的約束是控件到父布局的約束犯戏,控件和控件間的約束也是類似∷突穑現(xiàn)在再添加一個(gè)Button,這個(gè)Button在上一個(gè)Button的下方先匪,間距86dp(隨便給的),如下圖:

刪除約束####
刪除控件的約束有多種方式:
1.刪除整個(gè)布局的約束种吸,如下圖:

2.刪除某一控件的所有約束:選中該控件,右鍵呀非,選擇“Clear all Constraints”坚俗;或者,選中該控件岸裙,點(diǎn)擊左下角的X符號猖败;當(dāng)然如果你整個(gè)控件都刪除了,與之相關(guān)的約束也同時(shí)被刪除了降允。如下圖:

3.刪除某個(gè)控件的某個(gè)約束:選中該控件后恩闻,會(huì)在控件的上下左右顯示小圓圈,把鼠標(biāo)移到小圓圈上剧董,如果沒有約束幢尚,小圓圈是綠色的翅楼;如果已經(jīng)存在約束(每個(gè)小圓圈有且僅有一個(gè)約束),小圓圈是紅色的犁嗅,點(diǎn)擊變紅的小圓圈就能刪除對應(yīng)的約束了晤碘;或者從小紅圈重新拖拽一個(gè)新約束褂微,也會(huì)替換掉舊約束。如下圖:

查看控件屬性####
選中對應(yīng)的控件宠蚂,點(diǎn)擊右側(cè)的“Properties”,打開屬性面板童社,如下圖

默認(rèn)顯示較為常用的屬性求厕,如果需要顯示更多屬性,滾動(dòng)到底部扰楼,點(diǎn)擊View all properties查看所有的屬性。不確定這里是否囊括了所有的屬性值项栏,如果找不到蹬竖,那只能通過xml編寫了囖流酬。至于修改控件屬性列另,直接在該面板上修改即可。
下面重點(diǎn)關(guān)注屬性面板上的** Inspector**視圖页衙,如下圖:

先說說較為直白的地方:
1.ID欄:這里填寫的id就是標(biāo)識view的ID;
2.layout_width和layout_height:描述控件大小的店乐,可以直接填寫數(shù)值決定大小,也可以選擇wrap_content或match_parent(這兩個(gè)選項(xiàng)描滔,下面細(xì)說)踪古,還可以直接拖動(dòng)來決定控件的大小,如下圖:

新增一個(gè)Button拘泞,給上下左右添加上約束枕扫,此時(shí),Button默認(rèn)居中顯示烟瞧,選中該Button诗鸭,查看它的inspector,如下圖所示:

觀察紅色框內(nèi)的兩條軸强岸,一條是垂直顯示的砾赔,一條是水平顯示,這兩條軸是用于確定Button位置的〖嗣ぃ現(xiàn)在Button是居中顯示专普,相應(yīng)地可以看到這兩條軸上標(biāo)識的數(shù)值都是50,如果拖動(dòng)Button甚亭,可以看到相應(yīng)的數(shù)值會(huì)發(fā)生變化。例如役纹,水平向右拖動(dòng)Button暇唾,水平軸上的數(shù)值會(huì)隨之變大(值的范圍在0-100之間);按住水平軸上的數(shù)字進(jìn)行拖動(dòng)瘸味,能在水平方向上改變Button的位置够挂。
現(xiàn)在將水平軸移到到最右邊,數(shù)值為100枯冈,觀察預(yù)覽圖:

盡管已經(jīng)移動(dòng)到最右邊了办悟,但發(fā)現(xiàn)Button離最右邊還是有間距。這是因?yàn)樯a(chǎn)約束時(shí)炫加,系統(tǒng)默認(rèn)設(shè)置了8dp的間距(margin),如紅色框所示铺然√饺郏可以點(diǎn)擊右邊紅色框內(nèi)的數(shù)字修改間距烘挫。觀察預(yù)覽圖,發(fā)現(xiàn)每個(gè)約束上都有直線和波浪線其垄。其中直線表示的是間距(margin),波浪線則相當(dāng)是上面提到的水平軸或垂直軸卤橄,在這里拖動(dòng),用于改變Button的百分比位置喇颁。
每次添加約束都自動(dòng)添加一個(gè)間距的話,也是挺煩蔫浆,點(diǎn)擊下圖的紅色框位置可以這樣把它干掉:

控件的size###
上面提到了Button的layout_width和layout_height姐叁,和傳統(tǒng)布局相似,有三種:固定值外潜、
wrap_content和match_parent,如下圖所示:

1.<<< 圖案表示 wrap_content;
2.|-----| 圖案表示 固定值处窥;
3.波浪線圖案表示 match_parent,這里的match_parent和在RelativeLayout下的match_parent不同,RelativeLayout下的match_parent是用于填充滿當(dāng)前控件的父布局柜与,而這里的match_parent是用于填充滿當(dāng)前控件的約束規(guī)則嵌灰。假設(shè)將layout_width設(shè)置為match_parent,那么在水平方向上,不能再移動(dòng)控件迁匠,也就是上面說的水平軸移動(dòng)不再生效驹溃,預(yù)覽圖中,控件充滿約束規(guī)則亡哄。
當(dāng)layout_width或layout_height設(shè)置為match_parent時(shí)布疙,右上角會(huì)出現(xiàn)一個(gè)小三角,如下圖:

這個(gè)小三角的作用是:切換縱橫比約束截型,簡單來說就是設(shè)置寬高的比例宦焦!如下圖:

如果通過小三角設(shè)置縱橫比約束后,再通過手動(dòng)更改寬高數(shù)值酝豪,那后者將覆蓋前者精堕。
有了基本的了解后,我們來看看一些復(fù)雜點(diǎn)的場景夺英。
對齊###
對齊約束
實(shí)現(xiàn)兩個(gè)Button左對齊:添加兩個(gè)Button滋捶,一上一下,從Button A添加約束到Button B,如下圖操作添加對齊約束:

或者使用Align進(jìn)行對齊:選中所要對齊的控件载萌,點(diǎn)擊Align,最后選中對齊的方式即可巡扇,如下圖操作:

從Button A添加左對齊約束到Button B后厅翔,我們發(fā)現(xiàn),Button A將在水平方向上跟隨Button B移動(dòng)熊泵。
除了這種對齊方式外甸昏,Android studio還提供了Guideline和Baseline對齊方式!
考慮下面的場景:假如現(xiàn)在有兩個(gè)Button卒蘸,一上一下翻默,水平方向都距離距離左邊30%,如下圖:

按照我們上面所說的和泌,應(yīng)該這樣實(shí)現(xiàn):將兩個(gè)Button的水平軸數(shù)值設(shè)置為30即可。但現(xiàn)在我想同時(shí)讓這兩個(gè)按鈕距離左邊40%(原來是30%),或者改為距離右邊40%县恕。按照原來的做法剂桥,只能一個(gè)一個(gè)挨著去修改約束,有沒有更好的實(shí)現(xiàn)方式呢美尸?** Guideline**應(yīng)運(yùn)而生斟薇。
Guideline####
添加Guideline,如圖:

Guideline有兩種堪滨,一種是垂直方向的,一種是水平方向的遏乔,現(xiàn)在觀察一下Guideline,如下圖:

選中g(shù)uideline发笔,顯示一條虛線,頂部可以看到一個(gè)向左的箭頭鸯旁,下方有一個(gè)數(shù)字(假設(shè)是80)量蕊,
表示:距離父布局左邊80dp残炮;點(diǎn)擊頂部箭頭,發(fā)現(xiàn)箭頭向右了势就,下方有一個(gè)數(shù)字(假設(shè)是300)苞冯,表示:距離父布局右邊300dp;再次點(diǎn)擊頂部箭頭鞭达,發(fā)現(xiàn)箭頭變成了%符號,下方有一個(gè)百分比數(shù)字(假設(shè)是20%)畴蹭,表示在父布局水平方向20%的位置叨襟。我們可以拖動(dòng)guideline更改數(shù)值。
guideline的作用
簡單來說就是輔助控件確定位置的輔助線梳玫!
那如何實(shí)現(xiàn)上面提到的功能呢右犹?先添加一個(gè)垂直guideline,再添加兩個(gè)Button虱朵,分別設(shè)置按鈕右側(cè)到guideline的約束钓账,如下圖:

這樣梆暮,拖動(dòng)guideline,兩個(gè)Button都會(huì)隨著移動(dòng)了偿荷。
現(xiàn)在我們實(shí)現(xiàn)了不同控件以guideline為基準(zhǔn)唠椭,隨guideline移動(dòng)而移動(dòng)。那如何實(shí)現(xiàn)一個(gè)控件隨另一個(gè)控件移動(dòng)而移動(dòng)呢寺庄,** Baseline**登場啦力崇!
Baseline####
添加Baseline
選中Button,點(diǎn)擊下方的


為兩個(gè)Button添加Baseline約束
拖入兩個(gè)Button,選中Button A,添加Baseline后贞岭,拖拽到Button B即可,如下圖:

每個(gè)控件的baseline只有一個(gè)宪彩,從Button A拖拽到Button B讲婚,B會(huì)自動(dòng)生成baseline,現(xiàn)在兩個(gè)button已經(jīng)建立baseline約束了筹麸。我們發(fā)現(xiàn)雏婶,Button A只能水平方向上拖動(dòng),垂直方向上無法拖動(dòng)酵紫;Button B可以水平拖動(dòng)错维,也可以垂直拖動(dòng),而且在垂直方向上移動(dòng)時(shí)参歹,Button A也會(huì)隨之移動(dòng)隆判。由A到B添加了baseline,意味著A在垂直方向上的位置只能由B來決定了侨嘀,這就是Baseline的對齊作用。
自動(dòng)添加約束###
添加自動(dòng)約束的方式有兩種:一個(gè)是Autoconnect


1.Autoconnect默認(rèn)是關(guān)閉的欢峰,開啟后郎汪,添加控件時(shí),Android studio會(huì)檢測用戶的意圖抛计,自動(dòng)為控件添加約束照筑。比如,拖動(dòng)一個(gè)Button到預(yù)覽圖水平居中的位置波俄,AS檢測出可能是希望居中懦铺,就會(huì)顯示一條虛線,這時(shí)松開Button趁窃,就會(huì)自動(dòng)為Button添加約束急前,如下圖所示:

注意只有AS檢測出用戶意圖后(即預(yù)覽圖中出現(xiàn)虛線),才會(huì)自動(dòng)添加約束刨摩,否則也不會(huì)有約束世吨。
2.Infer Constraints和Autoconnect功能相似另假,但比后者更強(qiáng)大。Autoconnect是自動(dòng)為正在操作的控件添加約束己莺,而infer Constraints則是自動(dòng)為整個(gè)布局內(nèi)的控件添加約束戈轿。適用于較復(fù)雜的界面,為這樣的界面一鍵生成約束胜蛉!
需要注意的是:通過這兩種方式自動(dòng)添加的約束不一定符合要求色乾,這時(shí)候手動(dòng)修改就行了。
為自定義的控件添加約束####
Design界面運(yùn)行拖動(dòng)的控件都是系統(tǒng)預(yù)設(shè)的控件案怯,對于自定義的控件怎么辦呢澎办?
找不到可以直接將自定義控件拖進(jìn)面板的操作,可以先對一個(gè)基礎(chǔ)控件(如Button)進(jìn)行約束麦锯,然后再更改xml代碼扶欣,將自定義控件替換該Button。對于自定義的屬性也需要手動(dòng)編寫xml代碼昆著。
暫時(shí)能想到的就這些术陶,如有謬誤請指出煤痕,發(fā)現(xiàn)缺漏再補(bǔ)充摆碉,Thx.