Android控件之ConstraintLayout詳解

目錄:

一、爲何要用ConstraintLayout?
二、ConstraintLayout有哪些缺點?
三、怎麼使用ConstraintLayout。html

一、爲何要用ConstraintLayout?

  • 任何複雜的佈局只需一層(除非有嵌套的事件響應需求):

繪製過程當中的每一個階段都須要對視圖樹執行一次自頂向下的遍歷操做。所以,視圖層次結構中嵌入(或嵌套)的視圖越多,設備繪製視圖所需的時間和計算功耗也就越多。經過在 Android 應用佈局中保持扁平的層次結構,您能夠爲應用建立響應快速而靈敏的界面。android

  • 性能更出色

ConstraintLayout 在測量/佈局階段的性能比 RelativeLayout大約高 40%。 詳情參閱:解析ConstraintLayout的性能優點app

  • LinearLayout和RecyclerView的佈局能作到的ConstraintLayout都能作到,它們作不到的也能作到(這一點後面詳解)。

二、它有哪些缺點?

  • xml很囉嗦

主要體如今兩方面: 一、它須要經過詳盡的屬性來肯定自身位置,由於之前用LL或RL的寫法,有些屬性在父容器寫一次就夠,子容器就無需再寫一次,但這個是每一個容器都是獨立的,須要根據周圍的控件肯定自身的位置。因此這就引出了第二個囉嗦。 二、每一個View都要有與之對應的id。ide

  • 沒有gravity屬性,這裏後面會講到一個「拉力」的概念,這裏先簡單說一下,怎麼實現gravity=center這樣的效果呢?須要把每一個邊都與父容器的邊對應上(需設置4個屬性),由於四個邊都要拉扯以將控件拉到中間。

三、怎麼使用?

一、引入資源
compile 'com.android.support.constraint:constraint-layout:1.0.2'
複製代碼

二、熟悉它的屬性,主要有幾部分:

part1:相似於RelativeLayout的部分:

根據其餘控件給自身定位:佈局

layout_toRightOf="A"——>layout_constraintLeft_toRightOf="A"性能

根據父容器給自身定位:gradle

layout_alignParentRight=true——>layout_constraintRight_toRightOf=parent優化

相似的還有:ui

layout_constraintRight_toLeftOf layout_constraintRight_toRightOf layout_constraintTop_toTopOf layout_constraintTop_toBottomOf layout_constraintBottom_toTopOf layout_constraintBottom_toBottomOf //根據某控件的基線對齊 layout_constraintBaseline_toBaselineOfgoogle

part2:相似LinearLayout的weight效果

官方有張圖,如[圖1]所示,一般來講,LinearLayout的weight只能實現第四行的效果,但ConstraintLayout能夠實現下圖所有。

圖1
想實現相似LL(LinearLayout)的weight的效果,重點看每一個TextView的最下三行以及每一個TextView的 layout_width都是0,如下佈局能夠實現三個TextView。

<TextView android:id="@+id/tab1" android:layout_width="0dp" android:layout_height="30dp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toLeftOf="@+id/tab2" />


<TextView android:id="@+id/tab2" android:layout_width="0dp" android:layout_height="30dp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toRightOf="@id/tab1" app:layout_constraintRight_toLeftOf="@+id/tab3" />


<TextView android:id="@+id/tab3" android:layout_width="0dp" android:layout_height="30dp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toRightOf="@id/tab2" app:layout_constraintRight_toRightOf="parent" />
複製代碼

若是想實現2:1:1等分的效果,就如[圖1]的第四行,須要給每一個TextView分別添加以下屬性,並挨個設置值爲2,1,1便可:

app:layout_constraintHorizontal_weight
複製代碼

part3:如下是LinearLayout和RelativeLayout都作不到的,或者說是[要花很大的代價才能實現]這種表達是否是更準確點?

一、先說一下【鏈(Chains)】的概念:

ConstraintLayout中的控件想要定位準確,A控件是要依賴於父容器左側和B,而後B控件依賴於A和B,C依賴於B以及父容器的右側,就如圖2所示:

圖2.png

這個鏈表明瞭某種約束和拉力,上圖A,B,C之間存有間隙,(ps:若是要間隙等分的話,需設置layout_width=0dp),圖2每一個控件拉力都是同樣的,若是想實現[圖1]的其餘效果,實際上都是根據拉力大小變化來實現的,B拉力大一點,那A和C都更靠近B一點點,相似這樣的道理。

這裏要引出一個屬性:

layout_constraintHorizontal_chainStyle
複製代碼

該屬性有三個值:spread(鋪開),spread_inside(裏面鋪開), packed(擁擠),效果依次對應圖1的:第1行,第2行,第4行。 默認是spread。(ps:以上效果layout_width是固定值或wrap_content,若是是0的話就會相似第3行那樣)

圖1

二、用bias(偏斜)實現[圖1]第5行的效果

簡而言之就是調整C控件兩邊的拉力便可,對應的屬性是:

layout_constraintHorizontal_bias //水平線的拉力
layout_constraintVertical_bias  //垂直線的拉力
複製代碼

該屬性的值是0~1,默認是0.5,經過調整水平線的拉力便可達到第5行的效果了。

三、控件的寬高比

之前若是想要實現一個Banner寬高比是2:1這樣的,很麻煩,由於每一個機型分辨率有大有小,除非代碼運行才能知道屏幕寬度是多少,才能動態獲得屏幕寬度,在xml中根本沒法實現。 但ConstraintLayout提供了一個屬性就能實現:

app:layout_constraintDimensionRatio="W,2:1"
或
app:layout_constraintDimensionRatio="H,1:2"
複製代碼

注意:寬高須要設置0dp纔能有效果!

part4:關於Guideline(輔助線)

這個是爲了方便ConstraintLayout佈局,若是用過CAD的朋友就應該知道輔助線,用來輔助畫圖很方便,並且保存文件的時候該線是不會顯示到圖片上的,同理,這個也只是在寫xml的時候輔助用的,應用真正運行的時候是看不到的。

由於是一條線嘛,天然要區分水平仍是垂直的,因此就有一個屬性:

android:orientation
複製代碼

取值爲」vertical」和」horizontal」,跟RecyclerView同樣。

它還有一些屬性用來給輔助線找準位置,而後給輔助線命名個id,其餘控件只要基於該先找到本身的位置就好啦~

layout_constraintGuide_begin  
layout_constraintGuide_end
layout_constraintGuide_percent
複製代碼

它有兩種方式來找到本身的位置,一個是絕對值,也就是begin&end(取值爲dp),一個是百分比percent(取值爲0~1)。
當orientation爲vertical的時候,begin對應距離頂部,end對應距離底部。
當orientation爲horizontal的時候,begin對應距離左邊,end對應距離右邊。

真正使用的時候,就把Guideline看成一個View來用好了,Android Studio也會有預覽給你看的,記得要給它命名啊,否則其餘控件怎麼基於它定位呢,對吧?


更多請參閱:

一、鴻洋:ConstraintLayout 徹底解析 快來優化你的佈局吧
二、郭霖:Android新特性介紹,ConstraintLayout徹底解析
三、Google官方文檔——ConstraintLayout
四、Google官方文檔——Guideline
五、解析ConstraintLayout的性能優點

相關文章
相關標籤/搜索