佈局大殺器—ConstraintLayout

前言

Hi,大家好,看到標題後大家是不是一臉懵逼,這是啥?這小編搞事情?說好的六大布局咋又來個佈局殺手?這就是咱們公衆號和其他公衆號的不同,我們並不是照本宣科的講解Android知識,而是將項目當中實際運用到的並且是好用的東西分享給大家,還等什麼呢?趕緊開始我們的學習吧!!

引入

簡介:約束佈局(ConstraintLayout) 是一個ViewGroup,它的出現主要是爲了解決佈局嵌套過多的問題,以靈活的方式定位和調整View

說明:本博文是以ConstraintLayout1.1.3爲基礎編寫,不同的依賴版本有不同的屬性和方法,如果依照博文編寫demo發現編譯出錯,請自行研究更新版本的約束佈局或者與博主版本保持一致。

使用:檢查依賴項,是否添加此依賴庫。

//Android Studio2.3起,官方的模板默認使用ConstraintLayout。更新gradle插件版本之後,創建項目已經自動依賴,如果是老項目想要使用約束佈局依賴如此
dependencies {   
    implementation 'com.android.support.constraint:constraint-layout:1.1.3'   
}

使用

Android Studio2.3之後,創建一個layout文件,默認使用佈局如下:

<?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:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>

從上面發現有四個屬性:

layout_constraintBottom_toBottomOf="parent" //View下邊對齊parent底部
layout_constraintLeft_toLeftOf="parent"     //View左邊對齊parent左邊
layout_constraintRight_toRightOf="parent"   //View右邊對齊parent右邊
layout_constraintTop_toTopOf="parent"       //View上邊對齊parent上邊

除此之外還有幾個其他的常用屬性,表示View之間的關係

layout_constraintBottom_toTopOf="parent"    //View下邊對齊parent上邊
layout_constraintLeft_toRightOf="parent"    //View左邊對齊parent右邊
layout_constraintRight_toLeftOf="parent"    //View右邊對齊parent左邊
layout_constraintTop_toBottomOf="parent"    //View上邊對齊parent下邊

注意:此處parent可以換成其他想要與之關聯的View的控件ID

模板中聲明瞭一個TextView,且處於屏幕中間。如何做到的呢?上面四個屬性顧名思義都指定了TextViewParent(父佈局)的關係,約束佈局如果不指定水平和豎直方向的百分比,默認是50%,所以會居中。如果想要指定百分比使用如下屬性:(使用橫向比例需要指定左右關係,使用豎直比例需要指定上下關係)

layout_constraintHorizontal_bias="0.4"
layout_constraintVertical_bias="0.5"
這裏有人會問,按照設計圖的比例如何確定這個比例呢:這裏有一個公式和描述是經過驗證的
1.bias值=子View左相關的長度/(子View左相關的長度+其右相關的長度)
2.bias值與左相關的長度是成正比的,增大bias值,子View的左相關總是隨之增長。至於控件具體往左往右移動,則視子View與關聯控件的哪邊相關。

無圖無真相,計算說明這麼複雜,想要搞暈我?直接上圖!

所以我們知道:想要使用約束佈局固定一個View的位置,需要通過其與目標View相對的距離、位置,且從上(top)左(left)下(bottom)右(right)至少三個方位來說明關係

設置百分比佈局

ConstraintLayout 子佈局的寬或高設置爲0dp時,可以對寬或高設置百分比

 <Button
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:text="Hello World!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintHeight_percent="0.5"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintWidth_percent="0.5" />

使用layout_constraintHeight_percentlayout_constraintWidth_percent屬性設置橫豎方向佔比來確定寬度和高度,而不用具體尺寸,可以使用此屬性做一般View的屏幕適配。效果如圖所示:

img

設置寬高比例

layout_width或者 layout_height設置爲0dp時,還可以通過 layout_constraintDimensionRatio設置寬高比例。該比例默認表示 width:height的值。

<Button
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:text="Hello World!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintDimensionRatio="1:1"
        app:layout_constraintWidth_percent="0.5" />

使用layout_constraintDimensionRatio設置寬度和高度的比值來靈活設置View的尺寸。如果想要表示高度:寬度則可以配置屬性類似h,16:9的含義是 h:w=16:9 也可設置 w,9:16是一樣的。效果如圖所示:

img

強制約束

當一個view的寬或高,設置成wrap_content

<Button
        android:id="@+id/btn1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="佔位"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/btn2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="測試測試測試測試測試測試測試測試測試測試測試測試"
        app:layout_constraintLeft_toRightOf="@id/btn1"
        app:layout_constraintRight_toRightOf="parent"
        android:layout_marginTop="40dp"
        app:layout_constraintTop_toTopOf="@id/btn1" />

實現效果如圖所示:

img

納尼,怎麼回事,不是應該右邊不會超出父佈局的麼,我已經設置了layout_constraintRight_toRightOf="parent",這個就是設置了適應內容屬性後出現的問題,此時需要強制使用約束寬度的屬性 ,你會發現效果正常了。

app:layout_constrainedWidth="true"//在btn2上添加此屬性

控件鏈條(Chain)

可以通過 layout_constraintHorizontal_chainStylelayout_constraintVertical_chainStyle設置鏈式控件的樣式。這個屬性有點像 LinearLayout中的 weight 屬性平分佈局。使用此屬性,通常是權重分配不滿足需求,但是又需要居中或者分配View的空間

  • 先放一個官方解釋的示例圖

img

看完這個圖是不是還覺得一頭霧水,看起來很複雜的樣子?其實不然,在開發中靈活使用此屬性則能事半功倍且適配效果很好。使用此屬性之前,需要把你即將連成鏈條的View彼此之間建立關聯關係,水平方向則是控件彼此左右關聯,豎直方向則是上下關聯,每相鄰兩個View之間必須緊緊關聯ID。即是:將一個方向上的控件形成鎖鏈(相互依賴),默認屬性是spread

Spread Chain

img

Spread Inside Chain

//在btn1上配置
app:layout_constraintHorizontal_chainStyle="spread_inside" 
//左右靠邊,中間剩餘

img

Packed Chain

//在btn1上配置
app:layout_constraintHorizontal_chainStyle="packed" 
//三個控件彼此緊靠且整體居中

img

Packed Chain with Basis

//在btn1上配置
app:layout_constraintHorizontal_chainStyle="packed" 
app:layout_constraintHorizontal_bias="0.9"
//三個控件彼此緊靠且整體在橫方向設置比例處

img

結語

由於文章篇幅有限,且實際項目中還沒有研究到更多更好用的新屬性,暫時就告一段落,後期還會有關約束佈局的更多好的玩法推送給大家,如果有小夥伴發現更高效或者更實用的屬性,歡迎你們的留言,讓我們共同成長吧~

PS:如果還有未看懂的小夥伴,歡迎加入我們的QQ技術交流羣:892271582,裏面有各種大神回答小夥伴們遇到的問題哦~

img

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