ConstraintLayout的完全解析

簡介

ConstraintLayout也就是約束佈局,通過約束來實現佈局,感覺有點類似與RelatedLayout,但是比之更加的強大,使用ConstraintLayout可以減少佈局的嵌套層數,儘量的扁平化。傳統的佈局我們都是採用xml來操作,但是使用ConstraintLayout可以實現可視化的拖動來操作,我使用後某些時候拖動也不能完全準確,所以我認爲可以採用拖動加xml方式來佈局。
本文首先完成拖動佈局的基本操作,然後分析ConstraintLayout的xml屬性

可視化基本操作

轉換佈局

如果Android Studio自動默認創建的是傳統佈局,比如RelativeLayout,我們可以通過如下操作將它轉換成ConstraintLayout。

添加控件

比如我們想要向佈局中添加一個按鈕,那麼只需要從左側的Palette區域拖一個Button進去就可以了,如下圖所示。

這時新拖動的Button並沒有任何約束,左下角對應的Button有個紅色的感嘆號,鼠標放上去顯示缺少約束,切換到xml也可以看到這個Button報錯,如下圖所示:
這裏寫圖片描述

添加約束

Button沒有約束,並不知道顯示出現的位置,右邊的視圖叫BluePrint可以看到Button周圍有一些小圓圈、小點,如圖:

正方形實心點拖動可以調整大小,小圓點爲四個方向添加約束

除此之外,我們還可以使用約束讓一個控件相對於另一個控件進行定位。比如說,我們希望再添加一個Button,讓它位於第一個Button的正下方,並且間距64dp,那麼操作如下所示。

刪除約束

刪除約束的方式一共有三種,第一種用於刪除一個單獨的約束,將鼠標懸浮在某個約束的圓圈上,然後該圓圈會變成紅色,這個時候單擊一下就能刪除了,如下圖所示。

第二種用於刪除某一個控件的所有約束,選中一個控件,然後它的左下角會出現一個刪除約束的圖標,點擊該圖標就能刪除當前控件的所有約束了,如下所示。

第三種用於刪除當前界面中的所有約束,點擊工具欄中的刪除約束圖標即可,如下圖所示。

自動添加約束

不過如果界面中的內容變得複雜起來,給每個控件一個個地添加約束也是一件很繁瑣的事情。爲此,ConstraintLayout中支持自動添加約束的功能,可以極大程度上簡化那些繁瑣的操作。

自動添加約束的方式主要有兩種,一種叫Autoconnect,一種叫Inference,我們先來看第一種。

想要使用Autoconnect,首先需要在工具欄中將這個功能啓用,默認情況下Autoconnect是不啓用的,如下圖所示。
這裏寫圖片描述
Autoconnect可以根據我們拖放控件的狀態自動判斷應該如何添加約束,比如我們將Button放到界面的正中央,那麼它的上下左右都會自動地添加上約束,如下圖所示

接下來我們看一下Inference的用法。Inference也是用於自動添加約束的,但它比Autoconnect的功能要更爲強大,因爲AutoConnect只能給當前操作的控件自動添加約束,而Inference會給當前界面中的所有元素自動添加約束。因而Inference比較適合用來實現複雜度比較高的界面,它可以一鍵自動生成所有的約束。

下面我們就通過一個例子來演示一下Inference的用法,比如界面上現在有兩個TextView,兩個EditText,和兩個Button,我們把控件放置到合適的位置,然後點擊Inference按鈕,如下圖所示。

對齊方式

在工具欄中可以選擇控件的對齊方式,展開後有多種選擇方式,也可以右鍵選擇
這裏寫圖片描述

Guidelines

Guideline是ConstraintLayout的Guideline輔助對象的實用程序類,該輔助對象不會顯示在設備上,它被默認是View.GONE,而且不可改。另外,Guideline是專門爲ConstraintLayout創建的,也就是它僅也只能用於ConstraintLayou佈局。GuideLine其實就是一種約束規則,供其他視圖使用,以統一處理距離ConstraintLayout邊緣的距離,而不用單獨處理約束偏差。
首先來創建一個GuideLines,單位可以是dp,百分比,點擊進行切換


可以看到,我們給登錄按鈕的右邊向Guideline添加約束,登錄按鈕的下面向底部添加約束,並拖動按鈕讓它距離底部64dp。然後給註冊按鈕的左邊向Guideline添加約束,註冊按鈕的下面向登錄按鈕的下面添加約束。這樣就實現了讓兩個按鈕在水平方向上居中顯示,在垂直方向上都距離底部64dp的功能了。

Inspector

“Attributes”窗口在頂部顯示視圖的inspector,位於src和contentDescription的視圖屬性上方。inspector顯示UI元素的約束和邊距,以及用於調整元素沿水平和垂直軸的位置偏差的進度條。

①hide:使用此按鈕關閉“Attributes”窗口
②margin:通過單擊值並選擇不同的值來更改邊距
③height/width類型:表示控件的寬度和長度
③Bias:使用進度來改變具有相反約束的元素的水平和垂直約束偏移
④尺寸比(ratio):尺寸大小的比例
⑤約束:表示當前側面的約束,單擊後可以刪除約束

我們構建UI如下圖所示:

可以通過滑動bias的值,這個是代表佔比,下面會講到
這裏寫圖片描述

也可以在Inspect中修改寬高,Margin,Ratio,match_parent,wrap_content,fixed等,可以自行研究

相對定位屬性

  • 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

該屬性都形如layout_constraintXXX_toYYYOf,XXX代表自身的哪一邊(top,left,bottom,right),YYY表示相對於某個View的哪一邊,例如app:layout_constraintLeft_toRightOf=”@id/button1” ,表示的是控件自身的左側在button1的右側,app:layout_constraintBottom_toBottomOf=”parent”,表示控件自身底端和父控件底端對齊。

gone_margin

  • layout_goneMarginStart
  • layout_goneMarginEnd
  • layout_goneMarginLeft
  • layout_goneMarginTop
  • layout_goneMarginRight
  • layout_goneMarginBottom

舉例,當A控件 約束 在B控件的左邊,B控件GONE了,此時A會額外擁有一個margin的能力,來“補充”B消失的導致的“位移”。
下面看個例子:
這裏寫圖片描述
把左邊的Button設置爲GONE之後:
這裏寫圖片描述
可以看到右邊Button並沒有移動,這時的goneMarginLeft起作用了。

居中效果和bias

  • 父容器居中
    想要在父容器中居中,如果水平居中,給左邊界和右邊界添加約束,添加parent約束,以下代碼:
        <Button
        android:id="@+id/button7"
        android:layout_width="100dp"
        android:layout_height="wrap_content"
        android:text="Button"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        />
  • 在同級View之間居中
    如果想在居中在兩個View之間,類似的,把top約束到上面View的bottom,bottom約束到下面View的Top,就可以實現在這兩個View之間居中顯示

Bias
Bias代表傾向,分爲橫向和縱向的,默認等於0.5,要使用這個屬性需要添加View的上下或者左右的約束

        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintVertical_bias="0.5"

上面我們設置的居中顯示,默認爲0.5所以它是居中,我們可以更改這個值顯示在不同的位置,下圖是拖動方式來改變橫豎方向的Bias實現顯示的位置改變:

角度定位

角度定位是ConstraintLayout所特有的一種佈局方式,它可以約束一個控件的中心相對於另一個的角度和距離
layout_constraintCircle: 角度定位相對的另一個控件的id

layout_constraintCircleRadius: 到相對控件中心的距離

layout_constraintCircleAngle: 控件相對於另一個控件的角度

比例(Ratio)

當只有一個方向的約束時,可以使用ratio來定義View的寬高,例如:

<Button
        android:layout_width="200dp"
        android:layout_height="0dp"
        android:text="Ratio"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintDimensionRatio="2:1"
        app:layout_constraintTop_toTopOf="parent"/>

Chain鏈

Chain 鏈是由多個 Views 組合的,分爲水平和豎直的,所以要創建一個 Chain 鏈就需要先選擇多個想要鏈接到一起的 Views ,然後再右鍵選擇 ‘Center Horizontally’ 或者 ‘Center Vertically’ 來創建水平鏈或者垂直鏈。如下,創建一個水平鏈:

Chain 鏈模式一共有三種,分別爲:spread ,spread_inside 和 packed

  • spread:Chain 鏈的默認模式就是 spread 模式,它將平分間隙讓多個 Views 佈局到剩餘空間。
  • spread inside:它將會把兩邊最邊緣的兩個 View 到外向父組件邊緣的距離去除,然後讓剩餘的 Views 在剩餘的空間內平分間隙佈局。
  • packed:它將所有 Views 打包到一起不分配多餘的間隙(當然不包括通過 margin 設置多個 Views 之間的間隙),然後將整個組件組在可用的剩餘位置居中:

Chain也可以像LinearLayout一樣設置權重
app:layout_constraintHorizontal_weight="1"

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章