1. 程式人生 > >Android ConstraintLayout完全解析和效能分析(章節一)

Android ConstraintLayout完全解析和效能分析(章節一)

一、說在前面的話

在這裡預祝大家2019年:豬事順利,青春永豬,豬圓玉潤,豬籠入水—八面來財

對於這個已經出現了兩年的新佈局ConstraintLayout,之前只是作為知識瞭解並未在真正的使用它,今天讓我們來從幾個方面解讀ConstraintLayout並對它的效能做細緻化分析。

二、ConstraintLayout是什麼?

ConstraintLayout是Google在2016年的I/O大會上推出一款新型佈局方式,也是Android Studio 2.2中主要的新增的功能之一。目的是為了解決由於佈局巢狀過於複雜而帶來的頁面渲染效能問題。

可以這麼說,ConstraintLayout是RelativeLayout的升級版,它允許我們在Layout上設計子控制元件與子控制元件之間的位置關係,而且它遠比RelativeLayout在Android Studio中表現的效果更靈活、更容易使用。

下面是官網對它描述:

ConstraintLayout allows you to create large and complex layouts with a flat view hierarchy (no nested view groups). It’s similar to RelativeLayout in that all views are laid out according to relationships between sibling views and the parent layout, but it’s more flexible than RelativeLayout and easier to use with Android Studio’s Layout Editor.

三、為什麼要用ConstraintLayout?

我們都知道,在傳統的Android開發中,介面基本上都是靠編寫XAL程式碼完成的,雖然Android Studio也支援視覺化的方式編寫介面,但是操作起來異常的麻煩,而且佈局展示效果也達不到預想的效果,所以也不建議大家使用視覺化編寫Android程式的介面佈局。

但是ConstraintLayout出現就為了打破這一現狀。它和傳統編寫介面的方式恰恰相反,ConstraintLayout非常適合使用視覺化的方式來編寫介面,但是不太適合使用XAL的方式來進行編寫。當然,視覺化的背後仍然還是使用了XAL程式碼來實現的,只不過這些程式碼是由Android Studio根據我們的操作自動生成相應的佈局。

另一方面,ConstraintLayout還有一個比較重要的優點,它可以有效地解決佈局巢狀過多的效果。平時我們在編寫介面時,複雜的佈局往往會伴隨著多層佈局的巢狀,而巢狀越多,程式的效能也就越差。ConstraintLayout則是使用約束的方式來指定各個控制元件的位置和關係,它有點類似於RelativeLayout,但功能遠遠比RelativeLayout要強大。可以這樣說,RelativeLayout和LinearLayout能實現的效果,在ConstraintLayout完成都可以勝任,而且它們做不到的ConstraintLayout同樣也能做到,效能也會有很高的提升,關於效能的對比會在後面講到。

四、 讓我們愉快的開始

如果你使用的是Android Studio 2.3版本及以上版本時,在建立專案時預設會自動匯入ConstraintLayout的依賴並在建立佈局時預設佈局也會使用ConstraintLayout。但如果是使用Android Studio 2.2版本時可能就需要手動新增依賴,如下所示:

dependencies {
    implementation 'com.android.support.constraint:constraint-layout:1.1.3'
}

如果我們建立佈局時預設佈局不是ConstraintLayout時,我們可以通過將其轉換為ConstraintLayout:
在這裡插入圖片描述
需要注意一點時,轉換後之前的佈局樣式會失效,需要重新調整。

我們可以看到,現在主操作區域內有兩個類似於手機螢幕的介面,左邊的是預覽介面,右邊的是藍圖介面。這兩部分都可以用於進行佈局編輯工作,區別是左邊部分主要用於預覽最終的介面效果,右邊部分主要用於觀察介面內各個控制元件的約束情況。當然,如果不想看這樣預覽介面,可以在左上角點選在這裡插入圖片描述這個圖示,它分為三種模式:Design、BluePrint、Design+BluePrint,至於它們的展示介面可以自行體會。

基本操作

下面讓我們動起自己的小手開始具體操作吧。ConstraintLayout的基本用法很簡單,比如我們想要向佈局中新增一個按鈕,那麼只需要從左側的Palette區域拖一個Button進去就可以了,如下圖所示。
在這裡插入圖片描述
雖然現在Button已經新增到介面上了,但是由於我們沒有給Button新增任何的約束,因此Button並不知道自己應該出現在什麼位置。現在我們在預覽介面上看到的Button位置並不是它最終執行後的實際位置,如果一個控制元件沒有新增任何約束的話,它在執行之後自動位於介面的左上角。

那麼下面我們就來給Button新增約束,每個控制元件的約束都分為垂直和水平兩類,一共可以在四個方向上給控制元件新增約束,如下圖所示。
在這裡插入圖片描述
上圖中Button的上下左右各有一個圓圈,這圓圈就是用來新增約束的,我們可以將約束新增到ConstraintLayout,也可以將約束新增到另一個控制元件。比如說,想讓Button位於佈局的右下角,就可以這樣新增約束,如下圖所示。
在這裡插入圖片描述
我們給Button的右邊和下邊添加了約束,因此Button就會將自己定位到佈局的右下角了。類似地,如果我們想要讓Button居中顯示,那麼就需要給它的上下左右都新增約束,如下圖所示。
在這裡插入圖片描述
這就是新增約束最基本的用法了。

除此之外,我們還可以使用約束讓一個控制元件相對於另一個控制元件進行定位。比如說,我們希望再新增一個Button,讓它位於第一個Button的正下方,並且間距64dp,那麼操作如下所示。
在這裡插入圖片描述
現在新增約束的方式我們已經學完了,那麼該怎樣刪除約束呢?其實也很簡單,刪除約束的方式一共有三種,第一種用於刪除一個單獨的約束,將滑鼠懸浮在某個約束的圓圈上,然後該圓圈會變成紅色,這個時候單擊一下就能刪除了,如下圖所示。
在這裡插入圖片描述
第二種用於刪除某一個控制元件的所有約束,選中一個控制元件,然後它的左下角會出現一個刪除約束的圖示,點選該圖示就能刪除當前控制元件的所有約束了,如下所示。
在這裡插入圖片描述

第三種用於刪除當前介面中的所有約束,點選工具欄中的刪除約束圖示即可,如下圖所示。
在這裡插入圖片描述

至此我們把ConstraintLayout基本用法學完了,恭喜你現在就可以使用ConstraintLayout開發介面佈局了。不過有的同學可能發現了右邊的Properties區域中的Inspector。那就讓我們繼續吧。

Inspector

當我們選中任意一個控制元件的時候,在右邊的Properties區域中就會出現很多的屬性選項,如下圖所示:
在這裡插入圖片描述

在這裡我們就可以設定當前控制元件的所有屬性,如文字內容、顏色、點選事件等等。這些功能都非常簡單,我就不再進行詳細介紹,大家自己點一點就會操作了。

需要我們重點掌握的是Properties區域的上半部分,這部分也被稱為Inspector。
在這裡插入圖片描述

首先可以看到,在Inspector中有一個縱向的軸和一個橫向的軸,這兩個軸也是用於確認控制元件的位置。我們可以給Button的上下左右各加了一個約束,然後Button就能看居中顯示了,其實就是因為這裡的縱橫軸的值都是50。如果調整了縱橫軸的比例,那麼Button的位置也會隨之改變,如下圖所示:
在這裡插入圖片描述
不過,雖然我們將橫軸的值拖動到了100,但是Button並沒有緊貼到佈局的最右側,這是為什麼呢?實際上,Android Studio給控制元件的每個方向上的約束都預設添加了一個8dp的間距,從Inspector上面也可以明顯地看出來這些間距的值。如果這些預設值並不是你想要的,可以直接在Inspector上進行修改,如下圖所示:在這裡插入圖片描述
可以看到,修改成0之後Button右側的間距就沒了。

接下來我們再來學習一下位於Inspector最中間的那個正方形區域,它是用來控制控制元件大小的。一共有三種模式可選,每種模式都使用了一種不同的符號表示,點選符號即可進行切換。

  • 在這裡插入圖片描述 表示wrap content,這個我們很熟悉了,不需要進行什麼解釋。
  • 在這裡插入圖片描述 表示固定值,也就是給控制元件指定了一個固定的長度或者寬度值。
  • 在這裡插入圖片描述表示any size,它有點類似於match parent,但和match parent並不一樣,是屬於ConstraintLayout中特有的一種大小控制方式,下面我們來重點講解一下。
    首先需要說明,在ConstraintLayout中是有match parent的,只不過用的比較少,因為ConstraintLayout的一大特點就是為了解決佈局巢狀,既然沒有了佈局巢狀,那麼match parent也就沒有多大意義了。

而any size就是用於在ConstraintLayout中頂替match parent的,先看一下我們怎樣使用any size實現和match parent同樣的效果吧。比如說我想讓Button的寬度充滿整個佈局,操作如下圖所示。
在這裡插入圖片描述
可以看到,我們將Button的寬度指定成any size,它就會自動充滿整個佈局了。當然還要記得將Button左側的間距設定成0才行。

那有的朋友可能會問了,這和match parent有什麼區別呢?其實最大的區別在於,match parent是用於填充滿當前控制元件的父佈局,而any size是用於填充滿當前控制元件的約束規則。舉個例子更好理解,如果我們有一個新的Button,它的其中一個約束是新增到當前這個Button上的,那麼any size的效果也會發生改變,如下圖所示。
在這裡插入圖片描述
通過上圖的演示,相信你已經很好地理解any size的作用了。

Guideline

現在你已經對ConstraintLayout比較熟悉,並且能使用ConstraintLayout來編寫一些簡單的介面了。不過目前有一個問題可能還比較頭疼,剛才我們已經實現了讓一個按鈕居中對齊的功能,如果我們想讓兩個按鈕共同居中對齊該怎麼實現呢?

其實這個需求很常見,比如說在應用的登入介面,都會有一個登入按鈕和一個註冊按鈕,不管它們是水平居中也好還是垂直居中也好,但肯定都是兩個按鈕共同居中的。

想要實現這個功能,僅僅用我們剛剛學的那些知識是不夠的,這需要用到ConstraintLayout中的一個新的功能,Guideline。

下面我們還是通過實際操作來學習一下Guidelines的用法吧。比如現在已經向介面中添加了登入和註冊這兩個按鈕,如下圖所示。
在這裡插入圖片描述
然後我們希望讓這兩個按鈕在水平方向上居中顯示,在垂直方向上都距離底部64dp,那麼就需要先新增一個垂直方向上的Guideline,如下圖所示。
在這裡插入圖片描述
我來對上圖中的操作進行一下解釋。首先點選通知欄中的Guidelines圖示可以新增一個垂直或水平方向上的Guideline,這裡我們需要的是垂直方向上的。而Guideline預設是使用的dp尺,我們需要選中Guideline,並點選一下最上面的箭頭圖示將它改成百分比尺,然後將垂直方向上的Guideline調整到50%的位置,這樣就將準備工作做好了。

接下來我們開始實現讓兩個按鈕在水平方向上居中顯示,並距離底部64dp的功能,如下圖所示。
在這裡插入圖片描述
可以看到,我們給登入按鈕的右邊向Guideline新增約束,登入按鈕的下面向底部新增約束,並拖動按鈕讓它距離底部64dp。然後給註冊按鈕的左邊向Guideline新增約束,註冊按鈕的下面向登入按鈕的下面新增約束。這樣就實現了讓兩個按鈕在水平方向上居中顯示,在垂直方向上都距離底部64dp的功能了。

至此整個ConstraintLayout的使用都已經講解完畢。下面會講述佈局中每個屬性的具體含義,有興趣的同學可以檢視Android ConstraintLayout完全解析和效能分析(章節二)