一文看懂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
: 相對控件的idlayout_constraintCircleRadius
: 相對控件中心的距離,也就是圓的半徑layout_constraintCircleAngle
: 相對夾角 (從 0 ~ 360度)
例如,圖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
- Weighted chain
CHAIN_SPREAD_INSIDE
CHAIN_PACKED
設置權重
layout_constraintHorizontal_weight
layout_constraintVertical_weight
0x08 引用
https://developer.android.com/reference/android/support/constraint/ConstraintLayout
一文看懂ConstraintLayout的用法