Android Studio 2.2新增佈局——ConstraintLayout完全解析
0. 前言
ConstraintLayout是中主要的新增功能之一,我們都知道在傳統的Android開發中,介面基本主要是靠編寫XML程式碼完成的,雖然Android Studio也支援視覺化的方式來編寫介面,但是操作起來並不方便,而ConstraintLayout非常適合使用視覺化的方式來編寫介面,當然,視覺化操作的背後Android Studio會自動為我們生成XML程式碼。本篇轉載自郭大俠的部落格。根據原部落格做了稍微的整理和總結。
1. ConstraintLayout佈局的使用
1.1 新增依賴以及轉換預設佈局
為了使用ConstraintLayout,我們需要新增ConstraintLayout
現在開啟res/layout/activity_main.xml檔案,由於這是一個新建的空專案,Android Studio會自動幫我們建立好一個佈局預設的RelativeLayout,我們可以通過如下操作將它轉換成ConstraintLayout。如下圖所示。
轉換完成之後,原RelativeLayout中的內容也會自動轉換到ConstraintLayout中,比如圖中的TextView。如果你不需要它的話,可以選中這個控制元件,然後按鍵盤上的
我們可以看到,現在主操作區域內有兩個類似於手機螢幕的介面,左邊的是預覽介面,右邊的是藍圖介面。這兩部分都可以用於進行佈局編輯工作,區別是左邊部分主要用於預覽最終的介面效果,右邊部分主要用於觀察介面內各個控制元件的約束情況。
1.2 ConstraintLayout佈局的基本用法
ConstraintLayout的基本用法很簡單,比如我們想要向佈局中新增一個按鈕,那麼只需要從左側的Palette區域拖一個Button進去就可以了,如下圖所示。
雖說現在Button已經新增到介面上了,但是由於我們還沒有給Button新增任何的約束,因此Button並不知道自己應該出現在什麼位置。現在我們在預覽介面上看到的
那麼下面我們就來給Button新增約束,每個控制元件的約束都分為垂直和水平兩類,一共可以在四個方向上給控制元件新增約束,如下圖所示。
上圖中Button的上下左右各有一個圓圈,這圓圈就是用來新增約束的,我們可以將約束新增到ConstraintLayout,也可以將約束新增到另一個控制元件。比如說,想讓Button位於佈局的右下角,就可以這樣新增約束,如下圖所示。
我們給Button的右邊和下邊添加了約束,因此Button就會將自己定位到佈局的右下角了。類似地,如果我們想要讓Button居中顯示,那麼就需要給它的上下左右都新增約束,如下圖所示。
除此之外,我們還可以使用約束讓一個控制元件相對於另一個控制元件進行定位。比如說,我們希望再新增一個Button,讓它位於第一個Button的正下方,並且間距64dp,那麼操作如下所示。
現在新增約束的方式我們已經學完了,那麼該怎樣刪除約束呢?其實也很簡單,刪除約束的方式一共有三種,第一種用於刪除一個單獨的約束,將滑鼠懸浮在某個約束的圓圈上,然後該圓圈會變成紅色,這個時候單擊一下就能刪除了,如下圖所示。
第二種用於刪除某一個控制元件的所有約束,選中一個控制元件,然後它的左下角會出現一個刪除約束的圖示,點選該圖示就能刪除當前控制元件的所有約束了,如下所示。
第三種是用於刪除當前介面中的所有約束,點選工具欄中的刪除約束圖示即可,如下圖所示。
1.3 ConstraintLayout佈局的高階用法
1.3.1 Inspector
當你選中任意一個控制元件的時候,在右側的Properties區域就會出現很多的屬性選項,如下圖所示。在這裡我們就可以設定當前控制元件的所有屬性,如文字內容、顏色、點選事件等等。這些功能都非常簡單,這裡就不再進行詳細介紹,大家自己點一點就會操作了。
需要我們重點掌握的是Properties區域的上半部分(Inspector)。首先可以看到,在Inspector中有一個縱向的軸和一個橫向的軸,這兩個軸也是用於確定控制元件的位置的。我們剛才給Button的上下左右各添加了一個約束,然後Button就能居中顯示了,其實就是因為這裡縱橫軸的值都是50。如果調整了縱橫軸的比例,那麼Button的位置也會隨之改變,如下圖所示。
不過,雖然我們將橫軸的值拖動到了100,但是Button並沒有緊貼到佈局的最右側,這是為什麼呢?實際上,Android Studio給控制元件的每個方向上的約束都預設添加了一個16dp的間距,從Inspector上面也可以明顯地看出來這些間距的值。如果這些預設值並不是你想要的,可以直接在Inspector上進行修改,如下圖所示:
接下來我們再來學習一下位於Inspector最中間的那個正方形區域,它是用來控制控制元件大小的。一共有三種模式可選。
表示wrap content。
表示固定值,也就是給控制元件指定了一個固定的長度或者寬度值。
表示any size,它有點類似並用於替代match parent,是屬於ConstraintLayout中特有的一種大小控制方式,下面我們來重點講解一下。
首先需要說明,在ConstraintLayout中是有match parent的,只不過用的比較少,因為ConstraintLayout的一大特點就是為了解決佈局巢狀,既然沒有了佈局巢狀,那麼在ConstraintLayout中matchparent也就沒有多大意義了。
而any size就是用於在ConstraintLayout中頂替match parent的,先看一下我們怎樣使用any size實現和match parent同樣的效果吧。
比如說我想讓Button的寬度充滿整個佈局,操作如下圖所示。
那有的朋友可能會問了,這和match parent有什麼區別呢?其實最大的區別在於,match parent是用於填充滿當前控制元件的父佈局,而anysize是用於填充滿當前控制元件的約束規則。舉個例子更好理解,如果我們有一個新的Button,它的其中一個約束是新增到當前這個Button上的,那麼any size的效果也會發生改變,如下圖所示。而如果是match parent的效果,那麼高度會填充整個螢幕了。
1.3.2 Guidelines
剛才我們已經實現了讓一個按鈕居中對齊的功能,如果我們想讓兩個按鈕共同居中對齊該怎麼實現呢?
其實這個需求很常見,比如說在應用的登入介面,都會有一個登入按鈕和一個註冊按鈕,不管它們是水平居中也好還是垂直居中也好,但肯定都是兩個按鈕共同居中的。想要實現這個功能,僅僅用我們剛剛學的那些知識是不夠的,這需要用到ConstraintLayout中的一個新的功能,Guidelines。
我們希望讓下面兩個按鈕在水平方向上居中顯示,在垂直方向上都距離底部64dp,那麼就需要先新增一個垂直方向上的Guideline,如下圖所示。
Guideline預設是使用的dp尺,我們需要選中Guideline,並點選一下最上面的箭頭圖示將它改成百分比尺,然後將垂直方向上的Guideline調整到50%的位置,這樣就將準備工作做好了。接下來實現需求如下所示。
1.3.3 自動新增約束
如果介面中的內容變得複雜起來,給每個控制元件一個個地新增約束也是一件很繁瑣的事情。為此,ConstraintLayout中支援自動新增約束的功能,可以極大程度上簡化那些繁瑣的操作。自動新增約束的方式主要有兩種,一種叫Autoconnect,一種叫Inference,我們先來看第一種。
想要使用Autoconnect,首先需要在工具欄中將這個功能啟用,預設情況下Autoconnect是不啟用的,如下圖所示。
Autoconnect可以根據我們拖放控制元件的狀態自動判斷應該如何新增約束,比如我們將Button放到介面的正中央,那麼它的上下左右都會自動地新增上約束,如下圖所示。
然後我們在這個Button的下方再放置一個Button,效果如下。
可以看到,只需要將Button拖放到介面上,Autoconnect會判斷我們的意圖,並自動給控制元件新增約束。不過Autoconnect是無法保證百分百準確判斷出我們的意圖的,如果自動新增的約束並不是你想要的話,還可以在任何時候進行手動修改。總之,可以把它當成一個輔助工具。
以上是Autoconnect的用法,接下來我們看一下Inference的用法。Inference也是用於自動新增約束的,但它比Autoconnect的功能要更為強大,因為AutoConnect只能給當前操作的控制元件自動新增約束,而Inference會給當前介面中的所有元素自動新增約束。因而Inference比較適合用來實現複雜度比較高的介面,它可以一鍵自動生成所有的約束。
下面我們就通過一個例子來演示一下Inference的用法,比如介面上現在有兩個TextView,兩個EditText,和兩個Button,如下圖所示。
接下來我們先將各個控制元件按照介面設計的位置進行擺放,擺放完成之後點選一下工具欄上的Infer Constraints按鈕,就能為所有控制元件自動新增約束了,如下圖所示。
現在執行一下程式,最終效果如下圖所示:
2. 結束語
到這裡,我們基本就把ConstraintLayout中的重要用法都概括到了,ConstraintLayout有很多的功能仍然在改進當中。比如說,beta3版本中引入的Chains功能就是一個很強大的新功能,不過由於這個功能需要配合Android Studio 2.3來使用,而2.3目前也還沒有出正式版,因此ConstraintLayout的更多功能就讓我們拭目以待吧。