Android ConstraintLayout的基本使用

升級Android studio到2.3版本之后,發現新建Activity或fragment時,xml布局默認布局由RelativeLayout更改為ConstraintLayout了,既然已經推薦使用ConstraintLayout,學會如何使用就很有必要了。本文的主要是目標是:圖文結合,講講如何使用ConstraintLayout。

引入ConstraintLayout###

為了使用ConstraintLayout,需要在app/build.gradle文件中添加相應依賴:

dependencies {
    compile 'com.android.support.constraint:constraint-layout:1.0.1'
}

此前ConstraintLayout依賴庫版本號都帶有beta字眼,現在已經推出正式版本1.0.1。當然使用AS新建activity時,AS會自動添加這行依賴的。

創建ConstraintLayout###

新建ConstraintLayout布局文件后,打開如圖所示:

雖然ConstraintLayout和RelativeLayout等都是ViewGroup的子類,但RelativeLayout,FrameLayout等是位于widget包下的,ConstraintLayout則是在Support包下的。點擊界面左下角的“Design”和“Text”可以切換顯示視圖,“Design”視圖是可視化視圖,提供拖拽等功能實現界面布局;“Text”視圖是通過編寫xml代碼實現界面布局。

對于傳統布局,大部分開發者都是通過編寫xml代碼來現實布局的,顯得“Design”這個可視化工具相當的雞肋。但對于ConstraintLayout來說,卻很適合使用這個可視化工具來實現布局,今天將使用“Design”視圖來說明ConstraintLayout的使用。先來觀察“Design”視圖,

左側區域是預設的控件集合,頂部區域是操作欄位,右側區域則是預覽作用。

基本操作###

界面轉換####

如果布局不是ConstraintLayout,可以通過下圖操作進行轉換:


如果轉換前的界面是嵌套的,你可以選擇一層一層轉換,也可以選擇在根目錄轉換。使用的時候,發現這個轉換功能并不是很強大,不能確保轉換后界面保持一致。

添加控件####

如果想添加一個Button,只需從左側的Palette區域拖拽到預覽區域就可以了。拖拽完成后,會在布局中自動生成相應的xml代碼。“Design”工具是通過自動生成代碼來實現布局的,本質上還是通過xml實現布局。兩者是相互聯系的,其中一個發生改變,另一個會對應改變。下圖,添加一個Button:

通過拖拽,現在已經添加了一個Button。可以在“Text”視圖中看到,自動生成了xml代碼。雖然添加了Button,但由于還沒有給這個Button添加約束,所以在“Text”視圖下,可以看到Android Studio報錯了:沒有為view添加約束,但依然允許運行。由于沒有約束,Button并不知道自己所處的位置,實際運行效果和預覽效果是不一樣的,Button會出現在左上角。如果拖拽Button后,發現Button已經有約束,那么肯定是打開了AutoConnect開關,這個下文再詳說。

添加約束####

選中Button,能在上下左右看到四個空心小圓圈,把鼠標移動到小圓圈上,小圓圈會變成綠色。這四個小圓圈就是用來給Button添加約束的,實際上所有控件view都有這樣的4個小圓圈。現在給Button左邊和右邊各添加一個約束,如下圖所示:

只需選中小圓圈然后拖動鼠標到父布局邊框即可成功添加約束。上圖中,左側的預覽圖叫“Design”,右側藍色的視圖叫“Blueprint”,添加約束的操作在任意一個視圖上都可以完成。
上面的約束是控件到父布局的約束,控件和控件間的約束也是類似。現在再添加一個Button,這個Button在上一個Button的下方,間距86dp(隨便給的),如下圖:

刪除約束####

刪除控件的約束有多種方式:
1.刪除整個布局的約束,如下圖:

2.刪除某一控件的所有約束:選中該控件,右鍵,選擇“Clear all Constraints”;或者,選中該控件,點擊左下角的X符號;當然如果你整個控件都刪除了,與之相關的約束也同時被刪除了。如下圖:

3.刪除某個控件的某個約束:選中該控件后,會在控件的上下左右顯示小圓圈,把鼠標移到小圓圈上,如果沒有約束,小圓圈是綠色的;如果已經存在約束(每個小圓圈有且僅有一個約束),小圓圈是紅色的,點擊變紅的小圓圈就能刪除對應的約束了;或者從小紅圈重新拖拽一個新約束,也會替換掉舊約束。如下圖:

查看控件屬性####

選中對應的控件,點擊右側的“Properties”,打開屬性面板,如下圖

默認顯示較為常用的屬性,如果需要顯示更多屬性,滾動到底部,點擊View all properties查看所有的屬性。不確定這里是否囊括了所有的屬性值,如果找不到,那只能通過xml編寫了囖。至于修改控件屬性,直接在該面板上修改即可。
下面重點關注屬性面板上的** Inspector**視圖,如下圖:

先說說較為直白的地方:
1.ID欄:這里填寫的id就是標識view的ID;
2.layout_widthlayout_height:描述控件大小的,可以直接填寫數值決定大小,也可以選擇wrap_contentmatch_parent(這兩個選項,下面細說),還可以直接拖動來決定控件的大小,如下圖:

新增一個Button,給上下左右添加上約束,此時,Button默認居中顯示,選中該Button,查看它的inspector,如下圖所示:

觀察紅色框內的兩條軸,一條是垂直顯示的,一條是水平顯示,這兩條軸是用于確定Button位置的。現在Button是居中顯示,相應地可以看到這兩條軸上標識的數值都是50,如果拖動Button,可以看到相應的數值會發生變化。例如,水平向右拖動Button,水平軸上的數值會隨之變大(值的范圍在0-100之間);按住水平軸上的數字進行拖動,能在水平方向上改變Button的位置。
現在將水平軸移到到最右邊,數值為100,觀察預覽圖:

盡管已經移動到最右邊了,但發現Button離最右邊還是有間距。這是因為生產約束時,系統默認設置了8dp的間距(margin),如紅色框所示。可以點擊右邊紅色框內的數字修改間距。觀察預覽圖,發現每個約束上都有直線波浪線。其中直線表示的是間距(margin),波浪線則相當是上面提到的水平軸或垂直軸,在這里拖動,用于改變Button的百分比位置。
每次添加約束都自動添加一個間距的話,也是挺煩,點擊下圖的紅色框位置可以這樣把它干掉:

控件的size###

上面提到了Button的layout_widthlayout_height,和傳統布局相似,有三種:固定值
wrap_contentmatch_parent,如下圖所示:

1.<<< 圖案表示 wrap_content;
2.|-----| 圖案表示 固定值
3.波浪線圖案表示 match_parent,這里的match_parent和在RelativeLayout下的match_parent不同,RelativeLayout下的match_parent是用于填充滿當前控件的父布局,而這里的match_parent是用于填充滿當前控件的約束規則。假設將layout_width設置為match_parent,那么在水平方向上,不能再移動控件,也就是上面說的水平軸移動不再生效,預覽圖中,控件充滿約束規則。

layout_widthlayout_height設置為match_parent時,右上角會出現一個小三角,如下圖:

這個小三角的作用是:切換縱橫比約束,簡單來說就是設置寬高的比例!如下圖:

如果通過小三角設置縱橫比約束后,再通過手動更改寬高數值,那后者將覆蓋前者。

有了基本的了解后,我們來看看一些復雜點的場景。

對齊###

對齊約束
實現兩個Button左對齊:添加兩個Button,一上一下,從Button A添加約束到Button B,如下圖操作添加對齊約束:

或者使用Align進行對齊:選中所要對齊的控件,點擊Align,最后選中對齊的方式即可,如下圖操作:

從Button A添加左對齊約束到Button B后,我們發現,Button A將在水平方向上跟隨Button B移動。
除了這種對齊方式外,Android studio還提供了GuidelineBaseline對齊方式!

考慮下面的場景:假如現在有兩個Button,一上一下,水平方向都距離距離左邊30%,如下圖:

按照我們上面所說的,應該這樣實現:將兩個Button的水平軸數值設置為30即可。但現在我想同時讓這兩個按鈕距離左邊40%(原來是30%),或者改為距離右邊40%。按照原來的做法,只能一個一個挨著去修改約束,有沒有更好的實現方式呢?** Guideline**應運而生。

Guideline####

添加Guideline,如圖:

Guideline有兩種,一種是垂直方向的,一種是水平方向的,現在觀察一下Guideline,如下圖:

選中guideline,顯示一條虛線,頂部可以看到一個向左的箭頭,下方有一個數字(假設是80),
表示:距離父布局左邊80dp;點擊頂部箭頭,發現箭頭向右了,下方有一個數字(假設是300),表示:距離父布局右邊300dp;再次點擊頂部箭頭,發現箭頭變成了%符號,下方有一個百分比數字(假設是20%),表示在父布局水平方向20%的位置。我們可以拖動guideline更改數值。

guideline的作用
簡單來說就是輔助控件確定位置的輔助線!
那如何實現上面提到的功能呢?先添加一個垂直guideline,再添加兩個Button,分別設置按鈕右側到guideline的約束,如下圖:

這樣,拖動guideline,兩個Button都會隨著移動了。

現在我們實現了不同控件以guideline為基準,隨guideline移動而移動。那如何實現一個控件隨另一個控件移動而移動呢,** Baseline**登場啦!

Baseline####

添加Baseline
選中Button,點擊下方的

,就為view添加了baseline,如下圖:

為兩個Button添加Baseline約束

拖入兩個Button,選中Button A,添加Baseline后,拖拽到Button B即可,如下圖:

每個控件的baseline只有一個,從Button A拖拽到Button B,B會自動生成baseline,現在兩個button已經建立baseline約束了。我們發現,Button A只能水平方向上拖動,垂直方向上無法拖動;Button B可以水平拖動,也可以垂直拖動,而且在垂直方向上移動時,Button A也會隨之移動。由A到B添加了baseline,意味著A在垂直方向上的位置只能由B來決定了,這就是Baseline的對齊作用。

自動添加約束###

添加自動約束的方式有兩種:一個是Autoconnect

另一個是Infer Constraints

1.Autoconnect默認是關閉的,開啟后,添加控件時,Android studio會檢測用戶的意圖,自動為控件添加約束。比如,拖動一個Button到預覽圖水平居中的位置,AS檢測出可能是希望居中,就會顯示一條虛線,這時松開Button,就會自動為Button添加約束,如下圖所示:

注意只有AS檢測出用戶意圖后(即預覽圖中出現虛線),才會自動添加約束,否則也不會有約束。
2.Infer ConstraintsAutoconnect功能相似,但比后者更強大。Autoconnect是自動為正在操作的控件添加約束,而infer Constraints則是自動為整個布局內的控件添加約束。適用于較復雜的界面,為這樣的界面一鍵生成約束!
需要注意的是:通過這兩種方式自動添加的約束不一定符合要求,這時候手動修改就行了。

為自定義的控件添加約束####

Design界面運行拖動的控件都是系統預設的控件,對于自定義的控件怎么辦呢?
找不到可以直接將自定義控件拖進面板的操作,可以先對一個基礎控件(如Button)進行約束,然后再更改xml代碼,將自定義控件替換該Button。對于自定義的屬性也需要手動編寫xml代碼。

暫時能想到的就這些,如有謬誤請指出,發現缺漏再補充,Thx.

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容