前言
Google 在推出 Android Studio 2.2預(yù)覽版時(shí),為開(kāi)發(fā)者提供了一種新的布局霎槐,那就是 ConstraintLayout 布局桥嗤,當(dāng)時(shí)還不是正式版。但是在最近更新到 Android Studio 2.3之后菇篡,新建一個(gè)項(xiàng)目,打開(kāi) MainActivity 的布局文件吱型,你會(huì)發(fā)現(xiàn)根布局不再是 RelativeLayout逸贾,而是 ConstraintLayout,可見(jiàn) Google 對(duì)該布局看的還是挺重的津滞。那我們就有必要去學(xué)習(xí)一下 ConstraintLayout 布局了铝侵。
ConstraintLayout 與 RelativeLatout 很像,控件之間根據(jù)依賴(lài)關(guān)系而存在触徐,但它比 RelativeLayout 強(qiáng)大的多了咪鲜,簡(jiǎn)直可以說(shuō)是甩 RelativeLayout 幾條街。ConstraintLayout 可以有效的解決布局嵌套過(guò)多導(dǎo)致的性能問(wèn)題撞鹉,并且 ConstraintLayout 支持可視化的方式編寫(xiě)布局疟丙,簡(jiǎn)直是爽爆了颖侄。
使用
確保你的 Android Studio 版本是2.2或者以上。如果你的 Android Studio 版本是 2.3 正式版享郊,那么在你創(chuàng)建一個(gè)新項(xiàng)目時(shí)览祖,你的 Activity 布局文件的根布局默認(rèn)就是 ConstraintLayout。如果 AS 版本不是 2.3炊琉,需要在你的 app/build 文件中添加 ConstraintLayout 的依賴(lài)展蒂,如下:
compile 'com.android.support.constraint:constraint-layout:1.0.2'//正式版本
打開(kāi) res/layout/activity_main.xml 文件,由于是新建的項(xiàng)目苔咪,As 會(huì)自動(dòng)幫我們創(chuàng)建好一個(gè)布局锰悼,如下圖所示:(注意:我使用的 AS 版本是 2.3.1)
如果你用的 AS 版本低于 2.3,你只需要將布局轉(zhuǎn)換為 ConstraintLayout 即可团赏。如下圖:
我們可以看到箕般,現(xiàn)在主操作界面區(qū)域內(nèi)又兩個(gè)類(lèi)似手機(jī)屏幕的界面,左邊是預(yù)覽界面舔清,右邊是藍(lán)圖界面丝里。這兩個(gè)界面都可以進(jìn)行布局編輯操作,區(qū)別在于左邊用于預(yù)覽最終的界面效果鸠踪,右邊部分主要用于觀察控件之間的約束情況丙者。
基本操作
ConstraintLayout 支持可視化的方式編寫(xiě)界面,也就是說(shuō)你完全可以以拖拽的方式來(lái)完成界面的布局营密。比如我們?cè)诮缑嫣砑右粋€(gè) TextView 控件,那么我們只需在左側(cè) Palette 面板上拖一個(gè) TextView 就可以了目锭,如圖所示:
一個(gè) TextView 已經(jīng)添加到界面了评汰,但是由于我們沒(méi)有為這個(gè)控件添加約束,當(dāng)程序運(yùn)行時(shí)痢虹,會(huì)自動(dòng)位于界面左上角被去。
下面我們就為這個(gè) TextView 控件添加約束吧。每個(gè)控件的約束分為垂直和水平兩類(lèi)奖唯,一共可以在四個(gè)方向上為控件添加約束惨缆,如下圖所示:
上圖中 TextView 的上下左右各有一個(gè)圓圈,這些圓圈就是用來(lái)添加約束的丰捷,我們可以將約束添加到 ConstraintLayout 上坯墨,也可以將約束添加到另一個(gè)控件。例如:我們想讓這個(gè) TextView 位于布局的正中央病往,那么就可以這樣添加約束捣染,如下圖:
如上圖,我們?cè)?TextView 的上下左右分別添加了約束之后停巷,TextView 會(huì)居中央顯示耍攘。如果我們想讓這個(gè) TextView 居右上角顯示榕栏,我們只需在上右上添加約束即可。如下圖:
這就是添加約束最基本的方法了。
除此之外脉顿,我們還可以使用約束讓一個(gè)控件相對(duì)于另一個(gè)控件定位登馒。比如說(shuō),我們?cè)偬砑右粋€(gè)TextView渗磅,讓它位于第一個(gè) TextView 的下方,上間距為 20dp 检访,操作如下圖:
上面的間距我們可以拖動(dòng)來(lái)控制始鱼,或者通過(guò)右邊的 Properties 面板控制。我更傾向于右邊的 Properties 面板脆贵,它比拖動(dòng)能更精確控制間距的到小医清。
注意:當(dāng)為控件添加約束條件時(shí),最低需要添加兩個(gè)約束條件(左上卖氨、左下会烙、右上、右下)筒捺,當(dāng)你添加的約束條件不滿足時(shí)柏腻,在 Text 頁(yè)面,你的布局 XML 中就會(huì)有報(bào)紅線的控件系吭。
知道如何添加約束后五嫂,我們?cè)撛鯓觿h除約束呢?其實(shí)刪除約束也很簡(jiǎn)單肯尺,刪除約束的方式共有三中方式沃缘。第一種用于刪除一個(gè)單獨(dú)的約束,將鼠標(biāo)懸浮在某個(gè)約束的圓圈上则吟,該圓圈會(huì)變成紅色槐臀,點(diǎn)擊即可刪除。如下圖:
第二種用于刪除一個(gè)控件的所有約束氓仲,選中一個(gè)控件后水慨,會(huì)在控件左下角出現(xiàn)一個(gè)刪除約束的圖標(biāo),點(diǎn)擊該圖標(biāo)敬扛,就刪除了控件所有的約束條件晰洒。如下圖:
第三種用于刪除界面所有控件的約束條件,點(diǎn)擊即可刪除所有控件的約束條件舔哪。如下圖:
Properties 面板
我們知道了如何擺放控件后欢顷,下面來(lái)看下 Properties 面板的操作。當(dāng)你選中一個(gè)控件后捉蚤,右邊的 Properties 區(qū)域就會(huì)出現(xiàn)很多屬性選項(xiàng)抬驴。如下圖:
在這里我們可以設(shè)置當(dāng)前控件的所有屬性炼七,如文本內(nèi)容,字體大小布持,顏色豌拙,字體樣式等等。這些功能很簡(jiǎn)單题暖,大家點(diǎn)一點(diǎn)操作也下就會(huì)了按傅,這里就不啰嗦了。
這里重點(diǎn)介紹一下 Properties 區(qū)域的上半部分胧卤,這部分也稱(chēng)為 Inspector唯绍。
首先可以看到,在 Inspector 中有一個(gè)縱向的軸和一個(gè)橫向的軸枝誊,這兩個(gè)軸也是用于確定控件的位置的况芒。我們剛才給 TextView 的上下左右各添加了一個(gè)約束,然后 TextView 就能居中顯示了叶撒,其實(shí)就是因?yàn)檫@里縱橫軸的值都是50绝骚。如果調(diào)整了縱橫軸的比例,那么 TextView 的位置也會(huì)隨之改變祠够,如下圖:
不過(guò)压汪,雖然我們將縱軸橫軸的值都拖動(dòng)到了 100,但是 TextView 并沒(méi)有緊貼到布局的右上角古瓤,這是為什么呢止剖?實(shí)際上,Android Studio給控件的每個(gè)方向上的約束都默認(rèn)添加了一個(gè) 16dp 的間距湿滓,從 Inspector 上面也可以明顯地看出來(lái)這些間距的值滴须。如果這些默認(rèn)值并不是你想要的,可以直接在Inspector上進(jìn)行修改叽奥,如下圖:
可以看到將上邊距和右邊距設(shè)置為 0 之后,TextView 就緊貼在布局的右上角了痛侍。
接下來(lái)我們來(lái)看下 Inspector 最中間的那個(gè)正方形區(qū)域朝氓,它是用來(lái)控制控件大小的一共有三種模式可選,每種模式都使用了一種不同的符號(hào)表示主届,點(diǎn)擊符號(hào)即可進(jìn)行切換赵哲。
-
表示 wrap_content,這個(gè)我們很熟悉了君丁,不需要進(jìn)行什么解釋枫夺。
-
表示固定值,也就是給控件指定了一個(gè)固定的長(zhǎng)度或者寬度值绘闷。
-
表示 any size橡庞,它有點(diǎn)類(lèi)似于 match_parent较坛,但和 match_parent 并不一樣,是屬于 ConstraintLayout 中特有的一種大小控制方式扒最,下面我們來(lái)重點(diǎn)講解一下丑勤。
在 ConstraintLayout 中是有 match_parent 的,只不過(guò)用的比較少吧趣,因?yàn)?ConstraintLayout 的出現(xiàn)就是為為了解決布局嵌套法竞。既然沒(méi)了布局嵌套,那么 match_parent 就沒(méi)多大意義了强挫。
而any size就是用于在 ConstraintLayou t中頂替 match_parent 的岔霸,先看一下我們?cè)鯓邮褂?any size 實(shí)現(xiàn)和 match_parent 同樣的效果吧。比如說(shuō)我想讓 TextView 的寬度充滿整個(gè)布局俯渤,操作如下圖:
可以看到呆细,我們把 TextView 的寬度指定成 any size,它就會(huì)自動(dòng)充滿充滿這個(gè)布局稠诲,當(dāng)然要記得把 TextView 的左右間距設(shè)置成 0 才可以侦鹏。
那有的朋友可能會(huì)問(wèn)了,這和 match_parent 有什么區(qū)別呢臀叙?其實(shí)最大的區(qū)別在于略水,match_parent 是用于填充滿當(dāng)前控件的父布局,而 any size 是用于填充滿當(dāng)前控件的約束規(guī)則劝萤。舉個(gè)例子更好理解渊涝,如果我們有一個(gè)新的 TextView,它的其中一個(gè)約束是添加到當(dāng)前這個(gè) TextView 上的床嫌,那么 any size 的效果也會(huì)發(fā)生改變跨释,如下圖:
通過(guò)上圖的演示,相信可以很好理解 any size 的作用了厌处。
Guidelines (意譯:指導(dǎo)線)
上面講述了一些 ConstraintLayout 的基本操作鳖谈,可當(dāng)我們的布局過(guò)于復(fù)雜時(shí),以上的操作可能會(huì)達(dá)不到我們的需求阔涉。下面我們來(lái)學(xué)習(xí)下 Guidelines缆娃,意譯:指導(dǎo)線,我們可以把它理解為是一種"輔助線"瑰排,就好比我們學(xué)幾何圖形時(shí)做的輔助線一樣贯要。在這里,我們可以添加 Vertical Guideline 和 Horizontal Guideline 兩種輔助線椭住。如圖所示:
比如我們常見(jiàn)的登錄界面崇渗,界面會(huì)有兩個(gè) Button,顯示在中央。這時(shí)我們就需要添加 Vertical Guideline 輔助線宅广,才能讓這兩個(gè) Button 平分界面的寬度葫掉。如下圖:
如上圖,我們添加了一條 Vertical Guideline 輔助線乘碑,位置放在屏幕寬度的一半挖息,這樣兩個(gè) Button 就能平分屏幕的寬度了。上圖就錄制了添加 Vertical Guideline 輔助線的過(guò)程兽肤,gif太大的話會(huì)上傳不了套腹。
自動(dòng)添加約束
自動(dòng)添加約束的方式有兩種:一種是 Autoconnect,另一種是 Inference资铡。不過(guò)這兩種方式我在開(kāi)發(fā)中還是很少使用的电禀,即使一個(gè)控件自動(dòng)添加約束后,可能和我們想要的結(jié)果還是有很大差距的笤休,所以我還是習(xí)慣手動(dòng)給控件添加約束尖飞。這里就簡(jiǎn)單介紹一下吧,首先看下 Autoconnect店雅,我們需要啟用 Autoconnect 功能政基,默認(rèn)情況下是未啟動(dòng)的。如下圖所示:
打開(kāi) Autoconnect 功能后闹啦,它會(huì)根據(jù)我們拖放的狀態(tài)自動(dòng)判斷如何為控件添加約束(很多情況下沮明,還是需要手動(dòng)補(bǔ)充添加約束條件),比如我們將 Button 拖放到界面的正中央窍奋,那么控件的上下左右都會(huì)自動(dòng)添加上約束荐健。如下圖所示:
然后我們?cè)?Button 下面再放一個(gè) Button,效果如下:
可以看到琳袄,添加的 Button 只有左右自動(dòng)添加了約束江场,此時(shí)還需要手動(dòng)添加一個(gè)約束,控件才能正常顯示窖逗。Autoconnect 不能完全明白我們的意圖址否。總之碎紊,如果你感覺(jué) Autoconnect 方便的話在张,可以把它當(dāng)成一種輔助,但并不能完全靠它添加約束矮慕。
我們?cè)賮?lái)看下另一種自動(dòng)添加約束的功能 Inference,它比 Autoconnect 的功能更加強(qiáng)大啄骇。因?yàn)?Autoconnect 是給當(dāng)前操作的控件自動(dòng)添加約束痴鳄,而 Inference 是為當(dāng)前界面所有的控件添加約束。因此缸夹,Inference 比較適合用來(lái)實(shí)現(xiàn)復(fù)雜度較高的界面痪寻。
下面通過(guò)一個(gè)例子演示 Inference 的用法螺句。當(dāng)前界面有兩個(gè) TextInputLayout,和一個(gè) Button 按鈕橡类,我們使用 Inference 來(lái)意見(jiàn)生成約束蛇尚。如下圖所示:
好了,這里介紹了 ConstraintLayout 的一些基本用法顾画,通過(guò)本片文章的介紹取劫,相信你對(duì) ConstraintLayout 有了深入的認(rèn)識(shí)。還有就是 ConstraintLayout 的 Chains 功能研侣,我目前也正在研究谱邪,下面給出關(guān)于 Chains 文章的鏈接:https://blog.stylingandroid.com/constraintlayout-chains-spread-chains/ 。
目前 ConstraintLayout 版本才到 1.0.2庶诡,后續(xù)可能會(huì)出很多的功能惦银,讓我們拭目以待吧。