原文:ConstraintLayout basics create chains 作者:Mark Allison
Chain
鏈是一種特殊的約束讓多個 chain 鏈連接的 Views 能夠平分剩余空間位置。在 Android 傳統(tǒng)布局特性里面最相似的應該是 LinearLayout
中的權重比 weight ,但 Chains
鏈能做到的遠遠不止權重比 weight 的功能。
前面概要已經(jīng)提到了 Chain 鏈是由多個 Views 組合的,所以要創(chuàng)建一個 Chain 鏈就需要先選擇多個想要鏈接到一起的 Views ,然后再右鍵選擇 'Center Horizontally' 或者 'Center Vertically' 來創(chuàng)建水平鏈或者垂直鏈。如下,創(chuàng)建一個水平鏈:
首先,可以注意到 Chain 鏈兩邊末端的兩個 View 已經(jīng)存在了相對于父組件的左邊緣和右邊緣的約束。 Chain 鏈的創(chuàng)建定義的是 Chain 鏈組件之間的間隙關系,并不影響原有的非成員間的約束。如下剛剛創(chuàng)建后的圖中,有很多視圖上的標識符需要解釋一下。
觀察截圖,可以看到 Chain 鏈組件之間的連接類似于鏈條圖案,而邊緣兩端的 View 與 父組件之間的連接類似于彈窗圖案。最外面的連接圖案代表了 Chain 鏈的鏈接模式(chain mode),鏈接模式?jīng)Q定了 Chain 鏈如何分配組件之間的剩余空間,你可以從 Chain 鏈每個組件下面的 “轉(zhuǎn)換 Chain 模式” 按鈕來切換 Chain 鏈模式。
Chain 鏈模式一共有三種,分別為:spread
,spread_inside
和 packed
。
Chain 鏈的默認模式就是 spread
模式,它將平分間隙讓多個 Views 布局到剩余空間。
Chain 鏈的另一個模式就是 spread inside
模式,它將會把兩邊最邊緣的兩個 View 到外向父組件邊緣的距離去除,然后讓剩余的 Views 在剩余的空間內(nèi)平分間隙布局。
最后一種模式是 packed
,它將所有 Views 打包到一起不分配多余的間隙(當然不包括通過 margin 設置多個 Views 之間的間隙),然后將整個組件組在可用的剩余位置居中:
在 packed chain 鏈模式,打包在一起的 Views 組可以進一步通過控制修改 bias
值來控制打包組的位置,在例子中 bias
模式是 0.5
將 Views 組居中。
spread
和 spread inside
Chain 鏈可以設置每個組件的 weight 權重,這跟 LinearLayout
的 weight
權重設置很像。當前版本(Android Studio 2.4 alpha 7)的視圖編輯器不能直接操作設置這個權重,不過我們可以通過屬性視圖(properties 視圖)來手動設置屬性。
對特定的組件設置 spread
權重,首先得選擇這個 View 組件,假設該 View 是在一個水平的 Chain 鏈中,那么需要在屬性視圖(properties 視圖)中設置 android:layout_width="0dp"
然后修改 app:layout_constraintHorizontal_weight="1"
,如下所示:
這時候觀察 View
組件在 blueprint 藍圖視圖模式中的改變,它的上邊和下邊緣都從直線變成了類似手風琴的線條,這符號就表示了 spread
或 spread inside
Chain 鏈模式下的被設置了權重的組件。
同時要注意的是,在 packed
Chain 鏈模式下設置權重 weight
并沒有作用。就是說并不像 spread
和 spread inside
模式中表現(xiàn)的占據(jù)盡可能的剩余空間,在 packed
模式下該組件就會被收縮成 0 大小。
雖然假如在 XML 中存在特有的屬性設置 Chain 鏈模式會比較好,但事實上并沒有特有的屬性,而是現(xiàn)有的約束條件的一種組合。在 XML 中設置 Chain 鏈模式只需要設置好雙向互補的約束。本文中首個例子的 XML 源碼如下:
<?xml version="1.0" encoding="utf-8"?>
<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"
tools:context="com.stylingandroid.scratch.MainActivity">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
app:layout_constraintEnd_toStartOf="@+id/textView2"
app:layout_constraintHorizontal_chainStyle="spread"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="TextView" />
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
app:layout_constraintEnd_toStartOf="@+id/textView3"
app:layout_constraintStart_toEndOf="@+id/textView"
app:layout_constraintTop_toTopOf="parent"
tools:layout_editor_absoluteX="141dp"
tools:text="TextView" />
<TextView
android:id="@+id/textView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:layout_marginTop="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/textView2"
app:layout_constraintTop_toTopOf="parent"
tools:text="TextView" />
</android.support.constraint.ConstraintLayout>
在 textView
中設置了約束屬性 app:layout_constraintEndToStartOf="@+id/textView2"
,而相對的在 textView2
也設置了約束屬性 app:layout_constraintStart_toEndOf="@+id/textView"
,本質(zhì)上就是創(chuàng)建兩個約束條件,同一對錨點但是方向相反的約束條件,這就是 Chain 鏈的定義方式。
另外,textView
中的約束屬性 app:layout_constraintHorizontal_chainStyle="spread"
就是指定了鏈模式 spread
你可以通過修改成 spread inside
或 packed
來切換鏈模式,而且這個約束屬性必須在鏈頭,即是鏈組件中的第一個組件。
而設置鏈模式的 bias
可以通過設置約束屬性 app:layout_constraintHorizontal_bias="0.75"
從 0.0
- 1.0
。
最后,我們就可以通過設置屬性 android:layout_width="0dp"
以及 app:layout_constraintHorizontal_weight="1"
來設置 Chain 鏈中組件的權重。
更多建議: