1. 程式人生 > >一文看懂ConstraintLayout的用法

一文看懂ConstraintLayout的用法

users 百分比 style tom 子控件 code 比較 bottom inux

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 : 相對控件的id
  • layout_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>

  

設置寬度百分比布局:

  1. layout_width或者 layout_height 設置為0dp
  2. 設置 layout_constraintWidth_default="percent"或者 layout_constraintHeight_default="percent"
  3. 通過 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_widthlayout_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_chainStylelayout_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的用法