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版本添加的。
可以使用屬性有:
-
: 相對控件的idlayout_constraintCircle
-
: 相對控件中心的距離,也就是圓的半徑layout_constraintCircleRadius
-
: 相對夾角 (從 0 ~ 360度)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
設定為0dplayout_height
- 設定
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