Android ConstraintLayout詳解
AndroidStudio2.2開始,就推出了一個牛逼的佈局,ConstraintLayout,此佈局像是一個升級版的RelativeLayout,但是功能比RelativeLayout強大許多,號稱一層佈局就可以搞定複雜頁面。在AS2.2下還可以用拖拽控件的方式就行佈局(設計師的福音),不過本篇不講解拖拽控件的相關用法,主要講解一些相關屬性含義。
想學習拖拽控件設計ConstraintLayout的請點這裏。
Android官方教程在此。
本文講解參考這裏,需自備梯子。
開始!
相對位置
這個相對位置的設置有點類似RelativeLayout的layout_toLeftOf、alignParentLeft等這些屬性。
ConstraintLayout一共支持相對位置的屬性在此:
layout_constraintLeft_toLeftOf
layout_constraintLeft_toRightOf
layout_constraintRight_toLeftOf
layout_constraintRight_toRightOf
layout_constraintTop_toTopOf
layout_constraintTop_toBottomOf
layout_constraintBottom_toTopOf
layout_constraintBottom_toBottomOf
layout_constraintBaseline_toBaselineOf
layout_constraintStart_toEndOf
layout_constraintStart_toStartOf
layout_constraintEnd_toStartOf
layout_constraintEnd_toEndOf拿第一個屬性來說,layout_constraintLeft_toLeftOf=”@+id/id_first”,表示當前View的左邊界與id_first的View的做邊界對齊。其實這個屬性翻譯成中文就是:當前view的左邊對齊與引用view的左邊。
例子:
<Button android:id="@+id/buttonA" ... />
<Button android:id="@+id/buttonB" ...
app:layout_constraintLeft_toRightOf="@+id/buttonA" />
效果如下:
當然,這些屬性也支持設置爲對齊父佈局的左右前後。
<Button android:id="@+id/buttonB" ...
app:layout_constraintLeft_toLeftOf="parent" />
這樣,buttonB就依附在父佈局的左邊。類似Realitelayout的alignParentLeft。
margin屬性
這個屬性沒啥好說的,跟其他佈局的margin屬性差不多。支持的屬性如下:
android:layout_marginStart
android:layout_marginEnd
android:layout_marginLeft
android:layout_marginTop
android:layout_marginRight
android:layout_marginBottom
注意:如上圖,假如A緊貼父佈局的左側,B距離A 100dp,A設置爲gone後,則B距離父佈局的左側100dp。
goneMargin屬性
這個佈局比較有意思,還是拿上面的那副圖做示例,假設我們現在有這樣一個需求:假設A設置爲gone,後,B需要距離父佈局的左側200dp,怎麼辦?這時候,goneMargin屬性就派上用場啦,只要設置B的layout_goneMarginLeft=200dp即可。這樣,A不爲gone的時候,B距離A 100dp,A爲gone時,B距離父佈局左側200dp。
一共支持的屬性如下:
layout_goneMarginStart
layout_goneMarginEnd
layout_goneMarginLeft
layout_goneMarginTop
layout_goneMarginRight
layout_goneMarginBottomCentering positioning and bias ,設置居中或者按比例偏移。
假設我們要設置一個控件居中怎麼辦?很簡單,利用上面介紹過的屬性就可以辦到。
<android.support.constraint.ConstraintLayout ...>
<Button android:id="@+id/button" ...
app:layout_constraintHorizontal_bias="0.3"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent/> </>
bias支持的屬性如下:
layout_constraintHorizontal_bias
layout_constraintVertical_bias
ConstraintLayout本身支持minHeight、minWidht屬性,沒啥好說的。
注意ConstraintLayout不支持match_parent屬性,要用0dp代替,在加上設置特性的約束屬性,即可實現match_parent的效果。
Ratio 設置寬高比。
屬性如下:app:layout_constraintDimensionRatio=””
當前控件寬或高其一確定的話,可以使用ration屬性,根據確定的寬或高確定另外高或寬的大小。
<Button android:layout_width="wrap_content"
android:layout_height="0dp"
app:layout_constraintDimensionRatio="1:2" />
當前Button的width已經確定,height根據設置的比例=2×width
layout_constraintDimensionRatio接受的值是兩個float類型的比例,代表的含義是width:height。
ration屬性還支持這樣設置:
<Button android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintDimensionRatio="H,16:9"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
其中前面的字符H代表Height、W代表Width,谷歌官方的解釋是:
In that case, you need to indicate which side should be constrained, by adding the letter W (for constraining the width) or H (for constraining the height) in front of the ratio
翻譯過來就是說,W、H代表哪條邊應該被約束。什麼鬼?完全不理解。
還要經過我代碼測試,勉強知曉了前面H、W的意思。上面示例代碼的Button高已經確定,寬是高的十六分之九:9/16,如果前面設置位W的話,那麼寬的大小是高的九分之十六:16/9倍。
總結:假設比例設置爲a:b ,如果前面是H,不論哪一邊確定,另外一邊的大小都是確定邊的b/a倍;如果前面是W,不論哪一邊確定,另外一邊的大小都是確定邊的a/b倍。不知道谷歌是出於什麼哲學思想,感覺像是個bug。
Chains 鏈狀結構。
看圖如下:
Chain Style
要想chain style生效,必須設置當前鏈方向的邊爲wrap_content,比如上面的水平鏈,寬設爲wrap_content。還有就是控件要相互引用,比如A的右邊依賴B的左邊,B的左邊依賴A的右邊,都是設置。
chain style設置在第一個控件上
即設置在head上。屬性有兩個:
layout_constraintHorizontal_chainStyle
layout_constraintVertical_chainStyle
支持的值有三個:
CHAIN_SPREAD:均勻分佈控件。
CHAIN_SPREAD_INSIDE,同上,但是邊上的控件不均勻分佈。
CHAIN_PACKED:控件緊挨在一起。還可以通過bias屬性設置偏移量。
根據字面意思這三個屬性好理解,效果如下:
Weighted chains:
app:layout_constraintHorizontal_weight
app:layout_constraintVertical_weight
跟線性佈局的weight差不多,layout_constraintHorizontal_weight需要設置width=0dp,控件的大小根據設置的weight比例進行設置。Guideline
Guideline是一條隱形的線,這條線可作爲準線,根據此準線設置其他控件的位置。
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.constraint.Guideline
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/guideline"
app:layout_constraintGuide_begin="100dp"
android:orientation="vertical"/>
<Button
android:text="Button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/button"
app:layout_constraintLeft_toLeftOf="@+id/guideline"
android:layout_marginTop="16dp"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
上面代碼:guideline控件是一條隱形垂直的線,距離左邊距100dp,Button由於設置了left_toLeft,所以也距離左邊距100dp。
GuideLine支持的屬性:
layout_constraintGuide_begin:距離left或top的大小
layout_constraintGuide_end:距離right或bottom的大小
layout_constraintGuide_percent:float類型。距離left或top的大小的比例。
layout_constraintGuide_percent=”0.5” android:orientation=”vertical” ,那麼guideline距離左側的距離爲父佈局寬度的一半。