一文看懂ConstraintLayout的用法
ConstraintLayout
相對於 RelativeLayout
來說效能更好,佈局上也更加靈活。在最新的Google Android開發文件中是推薦使用 ConstraintLayout
的,下面來看看具體用法。
0x00 相對位置(Relative positioning)
這個比較簡單,看圖解釋,假設控制元件B要放在控制元件A的右側,可以使用 layout_constraintLeft_toRightOf
屬性。
<Button android:id="@+id/buttonA" ... /> <Button android:id="@+id/buttonB" ... app:layout_constraintLeft_toRightOf="@+id/buttonA" />
看圖2可以瞭解控制元件約束屬性代表的含義。
類似相對位置的約束屬性有:
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
0x01 外邊距(Margins)
這個屬性也好理解,看圖3
可以通過以下屬性設定一個控制元件相對另一個控制元件的外邊距:
android:layout_marginStart android:layout_marginEnd android:layout_marginLeft android:layout_marginTop android:layout_marginRight android:layout_marginBottom
屬性值必須是大於或者等於0。
接一下看一個 RelativeLayout
沒有的屬性:
0x02 Margins when connected to a GONE widget
當一個相對的控制元件隱藏時, ConstraintLayout
也可以設定一個不同的邊距:
layout_goneMarginStart layout_goneMarginEnd layout_goneMarginLeft layout_goneMarginTop layout_goneMarginRight layout_goneMarginBottom
具體的栗子下面會講到。
0x03 Centering positioning and bias
居中以及設定偏差
<android.support.constraint.ConstraintLayout ...> <Button android:id="@+id/button" ... app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent"/> </android.support.constraint.ConstraintLayout>
還可以設定bias屬性,表示子控制元件相對父控制元件的位置傾向,可以使用屬性:
layout_constraintHorizontal_bias layout_constraintVertical_bias
假設設定控制元件A相對父控制元件橫向偏差是30%:
<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"/> </android.support.constraint.ConstraintLayout>
0x04 弧形定位(Circular positioning)
這個屬性是在1.1版本新增的。
可以使用屬性有:
layout_constraintCircle layout_constraintCircleRadius layout_constraintCircleAngle
例如,圖6程式碼示例
<Button android:id="@+id/buttonA" ... /> <Button android:id="@+id/buttonB" ... app:layout_constraintCircle="@+id/buttonA" app:layout_constraintCircleRadius="100dp" app:layout_constraintCircleAngle="45" />
0x05 Visibility behavior
一般情況下,設定 GONE
屬性後,控制元件就不會出現在佈局中了,B控制元件對A控制元件的margin屬性也就沒有作用了。
但是 ConstraintLayout
能對已經設定 GONE
屬性的控制元件進行特殊處理。當A控制元件設定 GONE
之後,A控制元件相當於變成了一個點, B控制元件相對於對A的約束仍然是起作用的 。圖7的程式碼示例,A控制元件設定成了 GONE
,當B控制元件的 margin
屬性還是有作用的。
<android.support.constraint.ConstraintLayout ...> <Button android:id="@+id/buttonA" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="button A" android:visibility="gone" app:layout_constraintLeft_toLeftOf="parent" /> <!--當A控制元件設定Gone之後,B控制元件的margin屬性是起作用的,即左邊距還是30dp--> <Button android:id="@+id/buttonB" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="30dp" android:text="button B" app:layout_constraintLeft_toRightOf="@+id/buttonA" /> </android.support.constraint.ConstraintLayout>
然而有時候, B控制元件是不希望相對於隱藏控制元件的屬性還起作用 。這時候可以用到上面 0x02 提到的 goneMargin
屬性。
<android.support.constraint.ConstraintLayout ...> <Button android:id="@+id/buttonA" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="button A" android:visibility="gone" app:layout_constraintLeft_toLeftOf="parent" /> <!--當A控制元件設定Gone之後,希望B控制元件的左邊距為0dp,那麼可以設定layout_goneMarginLeft屬性--> <Button android:id="@+id/buttonB" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="30dp" android:text="button B" app:layout_goneMarginLeft="0dp" app:layout_constraintLeft_toRightOf="@+id/buttonA" /> </android.support.constraint.ConstraintLayout>
0x06 尺寸約束(Dimensions constraints)
設定最小或最大尺寸
可以使用以下屬性:
android:minWidth android:minHeight android:maxWidth android:maxHeight
當 ConstraintLayout
寬高設定為 wrap_content
時,以上屬性可以起作用。
設定百分比佈局
當 ConstraintLayout
子佈局的寬或高設定為0dp時,可以對寬或高設定百分比,例如設定一個按鈕的寬是螢幕寬度的30%,那麼可以這樣處理:
<android.support.constraint.ConstraintLayout ...> <!--按鈕width屬性設定為0dp,然後需要指定layout_constraintWidth_default,以及layout_constraintWidth_percent兩個屬性--> <Button android:id="@+id/buttonB" android:layout_width="0dp" android:layout_height="wrap_content" android:text="button B" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintWidth_default="percent" app:layout_constraintWidth_percent="0.3" /> </android.support.constraint.ConstraintLayout>
設定寬度百分比佈局:
-
layout_width
或者layout_height
設定為0dp - 設定
layout_constraintWidth_default="percent"
或者layout_constraintHeight_default="percent"
- 通過
layout_constraintWidth_percent
或者layout_constraintHeight_percent
指定百分比
設定寬高比例
當 layout_width
或者 layout_height
設定為0dp時,還可以通過 layout_constraintDimensionRatio
設定寬高比例。該比例表示 width:height
的值。
<Button android:layout_width="wrap_content" android:layout_height="0dp" app:layout_constraintDimensionRatio="1:1" />
當 layout_width
與 layout_height
都設定為0dp時,通過 app:layout_constraintDimensionRatio
指定寬高的比例。這時控制元件的寬高將按照該比例相對於父佈局的大小設定寬高。
<android.support.constraint.ConstraintLayout ...> <Button android:layout_width="0dp" android:layout_height="0dp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintDimensionRatio="h,16:9" app:layout_constraintTop_toTopOf="parent" /> </android.support.constraint.ConstraintLayout>
h,16:9
的含義是 h:w=16:9
也可設定 w,9:16
效果是一樣的。
0x07 Chains
在橫軸或或者數軸上的控制元件相互約束時,可以組成一個 鏈式約束 。
圖9中,A控制元件與B控制元件相互約束,這就是一個簡單的鏈式約束。
鏈頭
Chain Style
可以通過 layout_constraintHorizontal_chainStyle
或 layout_constraintVertical_chainStyle
設定鏈式控制元件的樣式。這個屬性有點像 LinearLayout
中的 weight
屬性平分佈局。
CHAIN_SPREAD CHAIN_SPREAD_INSIDE CHAIN_PACKED
設定權重
layout_constraintHorizontal_weight layout_constraintVertical_weight
0x08 引用
https://developer.android.com/reference/android/support/constraint/ConstraintLayout