1. 程式人生 > >ConstraintLayout用法及和RelativeLayout測試對比效能

ConstraintLayout用法及和RelativeLayout測試對比效能

ConstraintLayout 簡介:

ConstraintLayout是Android Studio 2.2中主要的新增功能之一,它可以在不巢狀任何佈局的情況下構建複雜的佈局.
它與RelativeLayout非常相似,所有的view都依賴於相鄰控制元件的相對關係.
而ConstraintLayout比RelativeLayout更加靈活,在AndroidStudio中進行拖拽即可完成佈局.

以往 我們都是通過巢狀或者使用RelativeLayout來完成複雜的佈局,但是通過使用Systrace大量測試表明:巢狀式層次結構和 RelativeLayout(會對其每個子物件重複測量兩次)的特性導致效能低下

  • ConstraintLayout和傳統巢狀式層次佈局寫法上的差異:

如上圖佈局,通過傳統巢狀方式來完成,佈局元素層次結構如下:

接著使用 ConstraintLayout 來構建相同的佈局

如上所示,ConstraintLayout實現的佈局擁有一個完全扁平的層次結構.這是因為 ConstraintLayout 允許我們構建複雜的佈局,而不必巢狀 View 和 ViewGroup 元素

  • ConstraintLayout和傳統巢狀式層次佈局效能上的差異:

在針對我們使用 ConstraintLayout 的佈局版本執行 Systrace 工具時,會發現,同樣 20 秒間隔週期內執行的測量/佈局次數大大減少,開銷也隨之大大減少.這種效能的改進很有意義.並且,我們構建 ConstraintLayout 版本的佈局時僅僅使用了佈局編輯器,而不是手工編輯 XML。而要使用 RelativeLayout 來實現同樣的視覺效果,我們很可能必須手工編輯 XML.

以下是通過Hierarchy Viewer針對和傳統巢狀方式實現的佈局和ConstraintLayout 效能測試對比:

傳統巢狀方式實現:(儘管這種型別的檢視層次結構還有改進的空間,但幾乎不可避免需要巢狀來實現)

ConstraintLayout實現:

我們主要關注上圖中的三個圓圈,從左到右依次,代表View的Measure,Layout和Draw的效能,不同顏色代表不同的效能等級:

綠色:表示該View的此項效能比該View Tree中超過50%的View都要快.例如,一個綠點的測量時間意味著這個檢視的測量時間快於樹中的檢視物件的50%

黃: 表示該View的此項效能比該View Tree中超過50%的View都要慢.例如,一個黃點佈局意味著這種觀點有較慢的佈局時間超過50%的樹檢視物件

紅: 表示該View的此項效能是View Tree中最慢的.例如,一個紅點的繪製時間意味著花費時間最多的這一觀點在樹上畫所有的檢視物件

紅色節點是代表應用效能慢的一個潛在問題,如何來分析和解釋紅點的出現原因?
    1)如果在葉節點或者ViewGroup中,只有極少的子節點,這可能反映出一個問題,應用可能在裝置上執行並不慢,但是你需要指導為什麼這個節點是紅色的,可以藉助Systrace或者Traceview工具,獲取更多額外的資訊
    2)如果一個檢視組裡面有許多的子節點,並且測量階段呈現為紅色,則需要觀察下子節點的繪製情況
    3)如果檢視層級結構中的根檢視,Messure階段為紅色,Layout階段為紅色,Draw階段為黃色,這個是比較常見的,因為這個節點是所有其它檢視的父類
    4)如果檢視結構中的一個葉子節點,有20個檢視是紅色的Draw階段,這是有問題的,需要檢查程式碼裡面的onDraw方法,不應該在那裡呼叫

瞭解完三個圓圈對應的意思後,對比兩者佈局,哪種方式效能更好就顯而易見了

以下是谷歌開發者官網針對ConstraintLayout與RelativeLayout效能測試對比報告

  • ConstraintLayout的用法:
    // 1.build.gradle中新增依賴:
    dependencies {
        implementation 'com.android.support.constraint:constraint-layout:1.1.0'
    }
    
    // 2.然後在xml佈局檔案中引用ConstraintLayout(最新的AS建立一個工程時,預設為ConstraintLayout佈局)
    <?xml version="1.0" encoding="utf-8"?>
    <android.support.constraint.ConstraintLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">
    
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Hello World!"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent" />
    
    </android.support.constraint.ConstraintLayout>
    // 3.接下來就可以在Design檢視頁面從左側拖拽需要的控制元件進去了
            (1).拖拽進來的控制元件可以在四個方向上給控制元件新增約束(點選拖拽過來的控制元件,上下左右會有四個圓圈,拖動到需要新增約束的控制元件上即可)
            (2).刪除約束
                刪除單個約束(將滑鼠放在某個約束的圓圈上,然後該圓圈會變成紅色,這個時候單擊一下就能刪除了)
                刪除一個控制元件的所有約束(點選一個控制元件,然後它的左下角會出現一個刪除約束的圖示,點選即可刪除當前控制元件的所有約束)
                刪除當前介面中的所有約束(點選工具欄中如上出現的'刪除約束的圖示'即可)
        還有一些其他用法:
        Inspector(調整橫縱軸控制位置;設定外邊距;設定控制元件大小三種模式:wrap content,固定值長寬指和any size)
        Guideline(工具欄中Guidelines圖示可以新增垂直或水平方向上的Guideline,然後新增控制元件約束到Guideline)
        自動新增約束(有兩種,分別是:AutoconnectInfer Constraints)
        Autoconnect: 工具欄中啟用,預設Autoconnect是不啟用的;將控制元件拖放到介面上,Autoconnect會判斷我們的意圖,並自動給控制元件新增約束
        Infer Constraints:它比Autoconnect功能更為強大,因為AutoConnect只能給當前操作的控制元件自動新增約束,Inference會給當前介面中的所有控制元件自動新增約束.
        (首先將各個控制元件按照介面設計位置進行擺放,然後點選一下工具欄上的Infer Constraints按鈕,就能為所有控制元件自動新增約束了)