約束(constraints)

2018-05-25 11:54 更新

原文:Constraintlayout basics create constraints 作者:Mark Allison


什么是約束(Constraints)

ConstraintLayout 的核心基礎(chǔ)就是創(chuàng)建約束。約束定義了布局內(nèi)兩個組件之間的關(guān)系,從而控制組件的布局位置。對于剛接觸 ConstraintLayout 但對 RelativeLayout 熟悉的開發(fā)者來說,約束布局的工作原理很像 RelativeLayout 中通過創(chuàng)建組件間關(guān)系來控制布局。

在 Android Studio 編輯器中創(chuàng)建約束

最容易創(chuàng)建約束布局的方式是通過 Android Studio 中的 design 可視化布局編輯器。本文章的例子都通過藍圖 Blueprint 視圖來查看展示,我們先簡單看看在 Blueprint 視圖中的 TextView

清晰地可以看到 TextView 組件,以及兩個箭頭符號表示在這個 TextView 組件上存在約束將它對齊到父組件 ConstraintLayout 的左邊緣和上邊緣。待會再來看它們是如何創(chuàng)建的,還可以看到存在 16dp 的外邊距讓父組件 ConstraintLayoutTextView 的組件邊緣之間保留了一些間隙。選擇 TextView 組件就會看到如下的縮放和約束錨點。

邊角上的小正方形是縮放的控制點,通過拖拉這些點就可以對 TextView 進行縮放。但是這個大多數(shù)情況并不是很適用,因為使用這種方式進行縮放后的組件將保持固定的尺寸,而我們往往更需要 TextView 根據(jù)具體情況響應(yīng)式大小。

每條邊中間的錨點就是約束錨點,我們就是用這個錨點來創(chuàng)建約束的。其中左邊和上邊的錨點里面有藍點表示這個錨點已經(jīng)存在了一個約束,相對的右邊和下邊的空心錨點則表示沒有約束。從這個例子,我們就可以看到 TextView 的布局位置就通過定義約束來對齊了父組件。

任何繼承了 TextView 的子組件都擁有另一個錨點:被稱為基線(baseline)。這就允許我們通過該錨點來調(diào)整組件內(nèi)的文字對齊基線。選擇 TextView 后出現(xiàn)下方按鈕,點擊其中的 ab 按鈕來顯示這個錨點。

TextView 上出現(xiàn)香腸狀的控制錨點就是基線約束錨點。我們可以通過給這個錨點添加約束就像下面提到給四個邊的約束錨點添加約束一樣。

另一個出現(xiàn)的下方按鈕中是取消約束按鈕(按鈕中存在 'x' ),點擊將移除該組件上的所有約束。

創(chuàng)建錨點,我們只需要簡單的從一個組件的錨點,拖動指向到另一個組件 View 的錨點。此處的例子,我們創(chuàng)建另一個 TextView (id 為 textView2 ,原來的那個 id 是 textview),而且 textView2 已有一個對齊父組件左邊的約束,我們再創(chuàng)建一個約束,從 textView2 的上邊到 textview 的下邊。而這個約束就會讓 textView2 對齊到 textview 正下方,如下所示:

在此處還要注意,我們創(chuàng)建的約束是從 textView2 的上邊到 textView 的下邊,當(dāng)我們選擇這兩個組件的時候,我們只會看到 textView2 的上邊約束錨點存在約束,而 textView 的下邊約束錨點是空心的不存在約束。

這樣的原因是約束是單向的(除非我們談?wù)摰募s束是鏈接 chains ),所以這里例子創(chuàng)建的約束是屬于 textView2 的,影響的也是 textView2 的布局位置是相對于 textView 的。因為該約束是只屬于 textView2 的,反過來不會影響 textView 的布局位置

上面講到的是同級組件間創(chuàng)建約束,而對于一個組件要創(chuàng)建相對于父組件的約束,則只是簡單的將約束拖的方向到合適的父組件邊緣即可,如下:

在 XML 中創(chuàng)建約束

對于想了解在可視化布局下真正的存儲的是如何的開發(fā)者,以下就是 上面例子的 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=".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_constraintLeft_toLeftOf="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_marginStart="16dp"
    android:layout_marginTop="8dp"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintTop_toBottomOf="@+id/textView"
    tools:text="TextView" />
</android.support.constraint.ConstraintLayout>

代碼中的約束都是以 app:layout_constraint 開頭的屬性。我們可以看到 ConstraintLayout 中所有子組件都存在這些屬性。讓他們對齊父組件的邊緣。你還可以看到 textView2 定義了一個約束聲明了該組件的上邊相對對齊到 textview 的下邊。

值得一提的是,這些屬性設(shè)置都是使用的 app 命名空間因為 ConstraintLayout 是像 Support libraries 也是作為庫引入。它屬于你的命名空間 app 而不是屬于安卓框架(使用命名空間 android )。

刪除約束

上面提到我們可以通過選中組件后出現(xiàn)的清空按鈕來清除所有的約束。最后,我們還要介紹的是只刪除其中一個約束。如果在 XML 源碼中可以直接去掉相應(yīng)的屬性。若使用的是可視化編輯器,則通過點擊約束錨點來去除約束條件。

以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號