使用 ConstraintLayout對(duì)Activity布局
Android Studio 2.3之后嗡靡,IDE默認(rèn)生成的Activity布局都是以ConstraintLayout做為根布局。
獲取官方示例代碼:
https://github.com/googlecodelabs/constraint-layout.git
平臺(tái)支持
ConstraintLayout最低兼容Android 2.3窟感;
目前Android Studio 2.3默認(rèn)使用ConstraintLayout作為布局文件的根布局讨彼;
想要使用ConstraintLayout,需在項(xiàng)目的build.gradle添加com.android.support.constraint:constraint-layout:XXX版本號(hào)依賴柿祈;
工作區(qū)
在工作區(qū)中有兩種預(yù)覽哈误,一種設(shè)計(jì)預(yù)覽,一種叫做藍(lán)圖的東西躏嚎。兩者可以輔助進(jìn)行布局預(yù)覽蜜自,非常不錯(cuò)。?
這里要介紹下卢佣,在工作區(qū)的左上角的幾個(gè)圖標(biāo)的作用重荠。
眼睛圖標(biāo):用來(lái)控制是否顯示約束的東西。?
磁鐵圖標(biāo):用來(lái)自動(dòng)吸附的東西虚茶,就是說(shuō)兩個(gè)按鈕放在一起的時(shí)候會(huì)自動(dòng)按照一定的約束條件進(jìn)行鏈接戈鲁。?
清理圖標(biāo):用來(lái)清除所有的約束,當(dāng)鼠標(biāo)放倒一個(gè)控件上時(shí)也會(huì)有一個(gè)清理圖標(biāo)出現(xiàn)嘹叫,點(diǎn)擊可以清除當(dāng)前選中的控件的約束婆殿。?
燈泡圖標(biāo):用來(lái)自動(dòng)推斷約束條件的東西,運(yùn)用這個(gè)可以更加智能快速的完成布局待笑。
約束
為了更好的理解約束鸣皂,下面來(lái)看一些源于谷歌案例:?
如上圖:?
簡(jiǎn)單來(lái)說(shuō)約束可以幫助你按照某種相互關(guān)系進(jìn)行布局抓谴,可以讓控件對(duì)齊等等操作暮蹂,在這里我們操作后面的按鈕并鏈接到前一個(gè)按鈕的右端寞缝,并且間隔56dp。哪么此時(shí)無(wú)論我移動(dòng)按鈕1到哪兒仰泻,按鈕2都將在按鈕1的右邊并間距56dp荆陆。
如上圖:在這個(gè)圖中我們看見有3種不同的手柄。
調(diào)整手柄
拖動(dòng)該手柄能幫助你調(diào)整整個(gè)控件的大小集侯。?
約束手柄
這個(gè)約束手柄位于控件的四邊被啼,在四邊上有四個(gè)小圓點(diǎn),拖動(dòng)該圓點(diǎn)并指向另外的控件的一邊棠枉,哪么可以讓該控件對(duì)其到指向的控件浓体。當(dāng)然你可以設(shè)置margin來(lái)提供對(duì)應(yīng)的間距。如果需要清理掉單個(gè)約束辈讶,點(diǎn)擊該圓點(diǎn)即可命浴。
基線手柄
該手柄僅僅出現(xiàn)在有文字的控件中使用,或者繼承TextView的控件中使用贱除,其作用是對(duì)齊兩個(gè)控件的文字基線生闲。
基線限制:?
- 基線只能鏈接到另一個(gè)控件的基線。?
- 基線也不能與手柄進(jìn)行鏈接月幌。
其他功能介紹
自動(dòng)鏈接
還記得上面說(shuō)到工作區(qū)的時(shí)候說(shuō)的自動(dòng)鏈接磁鐵圖標(biāo)么碍讯?
首先我們啟用該功能。然后新建界面并且拖動(dòng)一個(gè)圖片控件到中心部分扯躺,然后放開捉兴,此時(shí)會(huì)看見編輯器自動(dòng)為我們添加了圖片四邊的約束。
自動(dòng)推斷
自動(dòng)推斷也是用來(lái)輔助用戶創(chuàng)建控件約束的录语;其原理是綜合控件之間的關(guān)系創(chuàng)建對(duì)應(yīng)的約束條件轴术。要測(cè)試自動(dòng)推斷,首先我們關(guān)閉自動(dòng)鏈接功能钦无,此時(shí)我們添加一些控件逗栽,控件的布局如下,因?yàn)槲覀冴P(guān)閉了自動(dòng)鏈接失暂,并且采用拖動(dòng)關(guān)系進(jìn)行創(chuàng)建彼宠,此時(shí)界面上控件之間是沒(méi)有約束關(guān)系的。
基礎(chǔ)使用
ConstraintLayout翻譯成中文也稱為約束布局弟塞,在整個(gè)使用體驗(yàn)過(guò)程中真的是貫穿約束二字凭峡,這一節(jié)先來(lái)介紹一些基礎(chǔ)使用,后面你就會(huì)慢慢感受到約束布局的魅力决记。創(chuàng)建完工程后打開布局文件摧冀,底部切換Design的Tab上,可以看到整個(gè)操作界面
左上角的面板是放置了系統(tǒng)內(nèi)置各種各樣的控件,想要布局直接拖到到布局文件中即可(所見即所得)索昂,右邊的面板是選中布局文件中的控件時(shí)期各種各樣的空間屬性建车,ConstraintLayout最大的好處在于讓我們通過(guò)拖控件的形式進(jìn)行布局,并且不用擔(dān)心適配問(wèn)題椒惨。所以缤至,先來(lái)拖個(gè)控件試試看,將一個(gè)Button拖動(dòng)到屏幕正中央康谆,然后運(yùn)行顯示看看效果领斥。
模擬器運(yùn)行后的效果
而實(shí)際運(yùn)行后卻發(fā)現(xiàn),這個(gè)Button還是位于屏幕左上角沃暗,說(shuō)好的居中效果呢月洛?這里就要開始引入ConstraintLayout的約束概念,我們切換回去看xml的布局代碼孽锥,發(fā)現(xiàn)了兩個(gè)問(wèn)題膊存。第一,布局預(yù)覽時(shí)能夠看到顯示居中的Button忱叭,是因?yàn)榭丶傩栽O(shè)置中引用了兩個(gè)tools命名空間下的屬性隔崎。
我們都知道,這兩個(gè)屬性只在布局編輯器的預(yù)覽中有效韵丑,實(shí)際運(yùn)行效果是不生效的爵卒。第二,Button標(biāo)簽下有紅色波浪線警告撵彻,我們把鼠標(biāo)移到對(duì)應(yīng)位置會(huì)發(fā)現(xiàn)警告內(nèi)容钓株,告訴我們Button沒(méi)有任何約束設(shè)置,當(dāng)前效果只支持預(yù)覽陌僵,實(shí)際運(yùn)行后會(huì)返回到左上角去轴合,同時(shí)提示我們應(yīng)該給控件添加約束。
如何增加約束碗短?回到Design頁(yè)面受葛,對(duì)著控件上下左右四個(gè)原點(diǎn)拖動(dòng)添加對(duì)應(yīng)的約束即可
成功添加約束后,即可得到正常的運(yùn)行效果了偎谁。
實(shí)際操作不一定要在Tab总滩,也可以直接在Text頁(yè)面拖動(dòng)控件添加約束
成功實(shí)現(xiàn)添加約束后,可以看到Button多了下面幾個(gè)屬性設(shè)置
app:layout_constraintBottom_toBottomOf=”parent” 意思是Button底部的布局約束是位于parent的底部巡雨,parent是指包裹著它的ConstraintLayout闰渔,也可以設(shè)置指定某個(gè)控件的id,其他類似的屬性就不再贅述铐望,以上四個(gè)約束聯(lián)合起來(lái)便實(shí)現(xiàn)了Button的居中冈涧,ConstraintLayout總共有下面這些同類的屬性
你會(huì)發(fā)現(xiàn)ConstraintLayout非常靈活的把RelativeLayout的活給干了茂附,關(guān)于left、right督弓、top营曼、bottom、start咽筋、end、baseline的基準(zhǔn)可以參照下圖
relative-positioning-constraints
如果我想加多一個(gè)Button2并且將其放置到原先居中Button的右方并且與其底部對(duì)齊徊件,只需如下操作即可
并且你也可以發(fā)現(xiàn)奸攻,Button2依賴與Button后會(huì)隨著Button的移動(dòng)而跟著發(fā)生相對(duì)移動(dòng),目的是了保證我設(shè)置的依賴虱痕,時(shí)刻保持Button2就在Button的右邊睹耐,并且底部對(duì)齊。你也可以看到布局文件中也為Button2添加了如下兩個(gè)屬性
如果你已經(jīng)理解上面提到的屬性含義部翘,這里應(yīng)該不會(huì)有疑惑硝训。
介紹完上下左右的依賴設(shè)置后,下面介紹一些Margin屬性新思,除了Android常見的各種android:layout_marginXXX外窖梁,ConstraintLayout自行添加了如下屬性
這些設(shè)置生效于當(dāng)依賴的約束對(duì)象被設(shè)置visibility為gone時(shí),非常簡(jiǎn)單夹囚,讀者自行設(shè)置實(shí)踐對(duì)比即可纵刘,這里就不展示效果了。
聊完Margin后荸哟,再來(lái)介紹一下Bias假哎,ConstraintLayout新增了如下兩個(gè)屬性用于控制控件在水平和垂直方向在屏幕上的偏移比例
當(dāng)為目標(biāo)控件設(shè)置好橫縱向的約束時(shí)(app:layout_constraintLeft_toLeftOf=”parent”、app:layout_constraintRight_toRightOf=”parent”或者app:layout_constraintTop_toTopOf=”parent”鞍历、app:layout_constraintBottom_toBottomOf=”parent”)舵抹,這個(gè)兩個(gè)屬性才會(huì)生效。實(shí)際操作過(guò)程中劣砍,你會(huì)發(fā)現(xiàn)對(duì)著設(shè)置好橫縱向約束的Button進(jìn)行拖動(dòng)惧蛹,布局中的layout_constraintHorizontal_bias和layout_constraintVertical_bias會(huì)一直發(fā)生相應(yīng)的變化,如果你需要Button居中刑枝,那么直接將這兩個(gè)屬性的參數(shù)值設(shè)置為0.5即可赊淑。
進(jìn)階使用
看完基本使用,再來(lái)學(xué)習(xí)一些進(jìn)階技巧仅讽,這里先補(bǔ)充一個(gè)關(guān)于ConstraintLayout的知識(shí)點(diǎn)陶缺,與其他Layout不同之處在于,它的layout_width和layout_height不支持設(shè)置match_parent洁灵,其屬性取值只有以下三種情況:
wrap_content饱岸;
指定具體dp值掺出;
0dp(match_constraint),代表填充約束之意苫费,注意不要以為和match_parent是一樣的汤锨;
想想如果沒(méi)有ConstraintLayout,我們要讓一個(gè)控件的寬高按某個(gè)比例進(jìn)行布局應(yīng)該怎么做百框?有了ConstraintLayout后闲礼,我們可以使用layout_constraintDimentionRatio屬性設(shè)置寬高比例,前提是目標(biāo)控件的layout_width和layout_height至少有一個(gè)設(shè)置為0dp铐维,如下讓一個(gè)ImageView寬高按照2:1的比例顯示
layout_constraintDimentionRatio默認(rèn)參數(shù)比例是指寬:高柬泽,變成高:寬可以設(shè)app:layout_constraintDimensionRatio=”H,2:1”。
ConstraintLayout的鏈條(Chains)特性非常強(qiáng)大嫁蛇,在沒(méi)有ConstraintLayout之前锨并,線性布局我們主要都依靠LinearLayout來(lái)完成,有了ConstraintLayout之后睬棚,它把LinearLayout的活也干了第煮,例如要把按鈕水平排成一行,可以這樣操作
這樣ButtonA抑党、B包警、C就在水平方向形成了一條Chain,并且底部對(duì)齊底靠±恐海回去看xml文件,會(huì)見到ButtonA新增app:layout_constraintHorizontal_chainStyle的屬性設(shè)置苛骨,這個(gè)屬性在一條Chain中只會(huì)出現(xiàn)在第一個(gè)控件中篱瞎,這個(gè)控件是整條Chain的Head。
除了水平方向的layout_constraintHorizontal_chainStyle外還有垂直方向的layout_constraintVertical_chainStyle痒芝,兩者均有spread,spread_inside,packed這三種取值俐筋,如果將控件的layout_width和layout_height設(shè)置成為0dp,還可以配合layout_constraintHorizontal_weight严衬、layout_constraintVertical_weight兩個(gè)屬性實(shí)現(xiàn)和LinearLayout中設(shè)置layout_weight相同的效果澄者,具體的操作這里就不再展示了,下面一張圖告訴你Chain的強(qiáng)大之處请琳。
關(guān)于Chain的就介紹到此粱挡,進(jìn)階的最后一部分再介紹一下Guideline功能,如果我們需要對(duì)著屏幕的中軸線進(jìn)行布局俄精,就可以使用到Guideline進(jìn)行操作询筏,例如下面兩個(gè)Button分別分布在中軸線的左右兩側(cè)
從操作上我們可以看到Guideline也分為垂直和水平兩種,并且支持設(shè)置在屏幕中所處的位置竖慧,可以使用layout_constraintGuide_begin和layout_constraintGuide_end設(shè)置具體dp值嫌套,也可以使用layout_constraintGuide_percent來(lái)設(shè)置比例逆屡。實(shí)際上它也只是一個(gè)輔助我們布局的View而已,其源碼內(nèi)部實(shí)現(xiàn)也非常簡(jiǎn)單踱讨,并且默認(rèn)設(shè)置了visibility為gone魏蔗,關(guān)于ConstraintLayout的進(jìn)階使用便介紹到這里。
使用優(yōu)勢(shì)
關(guān)于ConstraintLayout的使用優(yōu)勢(shì)痹筛,我個(gè)人體驗(yàn)總結(jié)如下:
高效布局莺治,Android這么多年以來(lái)真正意義上的實(shí)現(xiàn)了所見即所得的拖曳方式布局,極大的提高開發(fā)效率帚稠;
輕松靈活的實(shí)現(xiàn)復(fù)雜的布局谣旁;
解決多重布局嵌套問(wèn)題,通過(guò)前面介紹你會(huì)發(fā)現(xiàn)ConstraintLayout真的是非常靈活翁锡,可以很大程度的避免Layout之間的嵌套蔓挖;
滿足屏幕適配的需求夕土,想想沒(méi)有ConstraintLayout之前的拖曳式布局馆衔,你就知道有多惡心;
google使用案例
1.首先選擇一個(gè)約束手柄怨绣,并按住鼠標(biāo)拖動(dòng)到另外一個(gè)控件的手柄原點(diǎn)上角溃,當(dāng)鏈接線變成綠色的時(shí)候松開鼠標(biāo)即可創(chuàng)建一個(gè)約束。
2.添加圖片控件篮撑,鏈接TextView控件的頂部手柄到ImageView底部手柄减细,并拖動(dòng)一定間距∮浚可以看出約束添加時(shí)文本控件自動(dòng)吸附到了圖片的底部未蝌。
3.拖動(dòng)圖片控件頂部手柄到根布局頂部。
4.最后我們同時(shí)添加圖片左邊與右邊的約束使其居中對(duì)齊茧妒。
5.添加基線約束萧吠。
屬性面板
首先我們?cè)谄聊簧咸砑右粋€(gè)圖片控件,并添加四邊約束到根布局桐筏,此時(shí)我們看見的界面是這樣的:
在屬性面板的上面部分是我們的檢查員(Inspector)纸型,在這個(gè)視圖中顯示了當(dāng)前選中的控件的約束情況。根據(jù)意思很好理解梅忌,這里就不詳述了狰腌。
使用ConstraintLayout示例
我們來(lái)看一下最終效果吧。
這種效果在機(jī)頂盒中是經(jīng)衬恋看到的琼腔,我們分析下我們使用普通的控件的實(shí)現(xiàn):
界面左側(cè)和右側(cè)高度是總高的1/3,
下面寬度為3/12、2/12踱葛、2/12展姐、2/12, 3/12;
中間大圖寬高分別為:1/2躁垛、 2/3