ConstraintLayout以及FlexBoxLayout使用,佈局性能測試工具

ConstraintLayout佈局以及性能測試

約束佈局的佈局方式
在這裏插入圖片描述
constranitLayout佈局內視圖的方位介紹

1 相對定位
在這裏插入圖片描述

<TextView
    android:id="@+id/TextView1"
    .../>

<TextView
    android:id="@+id/TextView2"
    ...
    app:layout_constraintLeft_toRightOf="@+id/TextView1" 

在這裏插入圖片描述
app:layout_constraintBaseline_toBaselineOf="@+id/TextView1"/>

其他的屬性如下:
layout_constraintLeft_toLeftOf,layout_constraintRight_toLeftOf,layout_constraintRight_toRightOf,layout_constraintTop_toTopOf,layout_constraintTop_toBottomOf
layout_constraintBottom_toTopOf,layout_constraintBottom_toBottomOf,layout_constraintStart_toEndOf,layout_constraintStart_toStartOf,layout_constraintEnd_toEndOf

2 角度定位

在這裏插入圖片描述

<TextView
android:id="@+id/TextView1"
… />

<TextView
    android:id="@+id/TextView2"
    ...
    app:layout_constraintCircle="@+id/TextView1"
    app:layout_constraintCircleAngle="120"
    app:layout_constraintCircleRadius="150dp" />

3 邊距
和普通視圖的margin屬性一樣用法,但約束佈局中有app:layout_goneMargin=“XXdp”,在相對位置的視圖爲gone的時候,生效margin屬性,如下:

4 居中和偏移
居中顯示方式,相對於parent視圖,上下左右分別對齊:
app:layout_constraintBottom_toBottomOf=“parent”
app:layout_constraintLeft_toLeftOf=“parent”
app:layout_constraintRight_toRightOf=“parent”
app:layout_constraintTop_toTopOf=“parent”

視圖本身的定位需要有頭有尾,左右,上下需要成對出現,才能生效。設置水平0.3偏移(居中是0.5偏移)
app:layout_constraintLeft_toLeftOf=“parent”
app:layout_constraintRight_toRightOf=“parent”
app:layout_constraintHorizontal_bias="0.3
在這裏插入圖片描述

bias範圍是0-1之間,
layout_constraintHorizontal_bias 水平偏移,layout_constraintVertical_bias 垂直偏移

5 尺寸約束
官方不推薦在ConstraintLayout中使用match_parent,設置爲0dp之後,使用左右上下對齊,可以保證撐滿整個屏幕
在設置寬高比的值的時候,還可以在前面加W或H,分別指定寬度或高度限制。 例如:
app:layout_constraintDimensionRatio="H,2:3"指的是 高:寬=2:3
app:layout_constraintDimensionRatio="W,2:3"指的是 寬:高=2:3

6 鏈

在這裏插入圖片描述
鏈的形成類似於雙向鏈表結構,必須有頭有尾,垂直和水平都行。

頭部第一個視圖設置layout_constraintHorizontal_chainStyle來改變整條鏈的樣式。chains提供了3種樣式,分別是:
CHAIN_SPREAD —— 展開元素 (默認);
CHAIN_SPREAD_INSIDE —— 展開元素,但鏈的兩端貼近parent;
CHAIN_PACKED —— 鏈的元素將被打包在一起。

在這裏插入圖片描述

題外:
彈性佈局FlexboxLayout
該佈局和css flex佈局功能幾乎一樣,但是沒有視圖回收功能,在佈局大量的子視圖的是性能差。
flex佈局屬性:flexDirection,flexWrap,justifyContent,alignItems,alignContent
flex子視圖屬性:layout_order,layout_flexGrow,layout_flexShrink,layout_alignSelf,layout_flexBasisPercent

FlexboxLayoutManager
該視圖管理器可以和recycleview配合使用,佈局屬性和功能和flexboxLayout一樣,但是具有視圖回收功能,性能比較好。

RecyclerView初始化:
mRecyclerView = (RecyclerView)findViewById(R.id.test_recyclerView);
FlexboxLayoutManager layoutManager = new FlexboxLayoutManager();
layoutManager.setFlexWrap(FlexWrap.WRAP);
layoutManager.setFlexDirection(FlexDirection.ROW);
layoutManager.setAlignItems(AlignItems.STRETCH);
layoutManager.setJustifyContent(JustifyContent.FLEX_START);
mRecyclerView.setLayoutManager(layoutManager);

adapter 的onBindViewHolder函數:
ViewGroup.LayoutParams lp = te.getLayoutParams();
if (lp instanceof FlexboxLayoutManager.LayoutParams) {
FlexboxLayoutManager.LayoutParams flexboxLp = (FlexboxLayoutManager.LayoutParams) lp;
flexboxLp.setFlexGrow(1.0f);
flexboxLp.setAlignSelf(AlignItems.FLEX_START); //子視圖可以覆蓋父容器的align的屬性
}

效果如下:
在這裏插入圖片描述

約束佈局的輔助對象

1 Optimizer
當我們使用 MATCH_CONSTRAINT 時,ConstraintLayout 將對控件進行 2 次測量,ConstraintLayout在1.1中可以通過設置 layout_optimizationLevel 進行優化,可設置的值有:
none:無優化
standard:僅優化直接約束和屏障約束(默認)
direct:優化直接約束
barrier:優化屏障約束
chain:優化鏈約束
dimensions:優化尺寸測量

2 Barrier
一個屏障,用於隔斷你所引用的視圖的邊緣,無大小,不佔空間
在這裏插入圖片描述

3 Group
視圖分組,可以對批量的視圖進行顯示和隱藏操作

4 Placeholder
佔位視圖,app:content="@+id/textview" 屬性可以設置佔位視圖應該顯示爲id是textview的視圖。

5.Guideline
輔助線,輔助定位的作用,在視圖中無大小,不佔空間,只用作約束定位。
android:orientation 垂直vertical,水平horizontal
layout_constraintGuide_begin 開始位置
layout_constraintGuide_end 結束位置
layout_constraintGuide_percent 距離的百分比

在這裏插入圖片描述

性能測試

構建如下佈局,採用約束佈局和普通佈局,然後對比measure到layout結束所消耗的時間。視圖樹結構,左邊是約束佈局,右邊是普通佈局:

在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述

measure()->layout()->draw(),假設有n個視圖,這個過程遵從樹的遍歷過程,那麼約束佈局的 measureLayout大概需要執行 n* measureLayout方法,
普通視圖大概需要執行 2nmeasureLayout方法,在relativelayout佈局中,還會主動measure子視圖兩次(一次是水平measure,一次是正常measure),因此普通視圖效率會更低,上面的
視圖樹,理論來說約束佈局對比普通視圖會減少一半的measureLayout時間,理論是理論,來實踐下吧。

1.addOnFrameMetricsAvailableListener
該方法設置給window對象,每次frame更新之後會回調方法,方法有個參數是FrameMetrics,可以查看很多耗時信息,這裏只使用它的LAYOUT_MEASURE_DURATION數據。

1.強制measurelayout過程:
在這裏插入圖片描述
2.每次回調之後,累加耗時,100次求取平均值。
在這裏插入圖片描述

經過多次測試,結果如下,簡單佈局就是上述所說的佈局樣式,複雜佈局是將上述佈局放入到recycleview中鋪滿屏幕:
在這裏插入圖片描述
可以看到,在不復雜的情況下,使用約束佈局和理論差不多兩倍關係,在複雜場景下,約束佈局也比普通佈局更加有優勢。

更多FrameMetrics信息查看:https://developer.android.com/reference/android/view/FrameMetrics

其實FrameMetrics的信息,用adb也可以收集出來,使用adb shell dumpsys gfxinfo com.example.myapplication framestats命令輸出FrameMetrics統計信息,
用echart表格可以展示如下:
在這裏插入圖片描述

dumpsys命令詳情:https://developer.android.com/studio/command-line/dumpsys

2.systrace的使用
使用該工具可以統計對應進程,運行時間,以及追蹤函數調用等等功能。該工具最大的好處可以用來查看是哪個函數對UIThread造成了卡頓,可以針對性的優化。

使用該工具的前提條件如下:
第一,android 4.1及以上的設備
第二,開啓調試模式,安裝你的應用
第四,需要安裝python2

首先進入你的systrace目錄:cd D:/android-sdk/platform-tools/systrace
在執行命令:python systrace.py --t 10 -o mynewtrace.htm -a cn.com.egova.egovamobile,
-t代表抓取時間,-o代表統計數據保存的文件位置,-a代表抓取的進程

上述命令可以收集智信的相關數據。
我在MorePluginManageActivity中進行滑動10s,統計數據如下,可以看到紅色的F是超過16ms的一幀,從上往下是函數調用鏈,從左往右是時間軸,其中obtainView ,setupGridItem
函數佔據了Choreographer#doFrame操作的大部分,在代碼裏面搜索可以知道這是grideview的adapter的內部函數,也就是自定義的 PluginGridAdapter,TopGridAdapter耗時過長

在這裏插入圖片描述

在代碼中設置Trace.traceBegin開始,Trace.traceEnd結束,代碼會將Trace包裹的這段代碼的統計信息輸出到統計文件中,在隨後的html頁面中可以進行展示

在這裏插入圖片描述在這裏插入圖片描述

systrace的使用以及參數配置請查看:https://developer.android.com/studio/profile/systrace/command-line

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章