Android開發 ConstraintLayout佈局的詳解

前言

   這篇博客其實拖了很久,原因是我早就已經徹底掌握了ConstraintLayout的使用,沒有動力記錄我已經特別熟練的技能了,所以一直懶得在寫博客了。 但是,覺得還是應該系統的整理一篇博客幫助他人學習。

在學習之前還是先要了解下約束佈局的優勢:

  1.嵌套少,性能提高。因爲View位置是互相關聯的,所以不需要像線性佈局一樣需要有很多父類容器輔助View定位。

  2.更快的編寫xml佈局,提高工作效率。熟練後可以使用Android studio快速拖拉組件來實現佈局,但是前期建議好好了解ConstraintLayout的屬性

  3.View的定位靈活度更大,可以動態的跟隨其他View的位置改變而改變。

  4.可閱讀性強,這點可能很多人會質疑:“一堆View平鋪有什麼閱讀性啊”。 但是事實是,嵌套多層的線性佈局或者相對佈局反而更難以閱讀,因爲你需要關注父類佈局提供的輔助定位信息。

學習定位屬性

這裏的定位屬性指的是 layout_constraintTop_toTopOf  、layout_constraintTop_toBottomOf 、 layout_constraintStart_toEndOf 等等此類屬性。

爲了方便後續理解,這裏說明下此類定位屬性的意思。此類定位屬性在文本上想表達的是 當前View定位View 什麼位置上。

這裏舉幾個例子,例如:

layout_constraintTop_toBottomOf   這個屬性的意思是 當前View的上邊(Top)在 目標View的下邊(Bottom)

layout_constraintTop_toTopOf   這個屬性的意思是 當前View的上邊(Top) 在 目標View的上邊(Top)

 

這個時候估計有人會疑問,什麼是當前View,什麼是定位View啊。

當前View是指:你添加了 layout_constraintTop_toBottomOf  這個屬性的View

定位View是指:app:layout_constraintTop_toBottomOf="@id/quit"   後面添加的id ,這裏@id/quit 就是定位的View。 所以,使用約束佈局還有一個特點就是基本上每一個View都要寫上id。

layout_constraintTop_toBottomOf   當前View的Top在目標View的Bottom

效果圖(注意圖片中的箭頭):

 

 xml

    <Button
        android:id="@+id/btn2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="50dp"
        android:text="按鍵2"
        app:layout_constraintTop_toBottomOf="@id/btn1" />

 

方便觀看這裏增加了上邊距50dp

layout_constraintBottom_toTopOf當前View的Bottom在目標View的Top

效果圖:

 

 

 xml

    <Button
        android:id="@+id/btn2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="按鍵2"
        android:layout_marginBottom="50dp"
        app:layout_constraintBottom_toTopOf="@id/btn1" />

layout_constraintLeft_toRightOf 與 layout_constraintStart_toEndOf  當前View的Left在目標View的Right

layout_constraintLeft_toRightOf 與 layout_constraintStart_toEndOf 這2個屬性其實都是一個意思,都是當前View的Left在目標View的Right。

爲什麼google會設計2個功能一樣的屬性呢? 因爲阿拉伯語,我們正常的閱讀習慣是從左到右,而阿拉伯語的習慣是從右到左。所以語言切換後整體View的佈局位置也要跟隨改變。當時,如果你只開發國內App其實用2個之間的任意一個屬性都可以。

效果圖

 

 

 xml

    <Button
        android:id="@+id/btn2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="按鍵2"
        app:layout_constraintStart_toEndOf="@id/btn1"
        app:layout_constraintTop_toBottomOf="@+id/btn1" />

在上面我使用了Start_toEndOf 所以效果圖上按鍵2的左邊依附在按鍵的右邊上,但是因爲Top_toBottomOf的關係,按鍵2的上邊又在按鍵1的下邊上。

layout_constraintRight_toLeftOf 與 layout_constraintEnd_toStartOf  當前View的Right在目標View的Left

與上面的差不多,舉一反三也可以理解。

效果圖:

 

 

 xml

    <Button
        android:id="@+id/btn2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="按鍵2"
        app:layout_constraintEnd_toStartOf="@id/btn1"
        app:layout_constraintTop_toBottomOf="@+id/btn1" />

layout_constraintTop_toTopOf 當前View的Top在目標View的Top

這裏要介紹一個關鍵字 parentparent會經常使用當前View想依附到ConstraintLayout 佈局本身的四個邊的位置上時,就可以使用parent。 例如希望一個按鈕依附到ConstraintLayout 上邊 就可以 使用 app:layout_constraintTop_toTopOf="parent"

效果圖:

 

 xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.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:background="@color/white"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:id="@+id/btn1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="20dp"
        android:layout_marginTop="20dp"
        android:text="按鍵1"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/btn2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="按鍵2"
        app:layout_constraintTop_toTopOf="@+id/btn1"
        app:layout_constraintStart_toEndOf="@+id/btn1"/>

</androidx.constraintlayout.widget.ConstraintLayout>

這裏按鍵1依附了父類佈局ConstraintLayout 的 左邊與上邊, 按鍵2佈局也寫入 app:layout_constraintTop_toTopOf="@+id/btn1" 依附在按鍵1的上邊。 這裏可以看到按鍵2即使沒有寫layout_marginTop="20dp" 也依然與按鍵1的top邊對齊。

layout_constraintBottom_toBottomOf  當前View的Bottom在目標View的Bottom

與上面的差不多,舉一反三也也可以理解。

效果圖:

 

 xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.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:background="@color/white"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:id="@+id/btn1"
        android:layout_width="wrap_content"
        android:layout_height="80dp"
        android:layout_marginStart="20dp"
        android:layout_marginTop="20dp"
        android:text="按鍵1"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/btn2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="按鍵2"
        app:layout_constraintBottom_toBottomOf="@id/btn1"
        app:layout_constraintStart_toEndOf="@+id/btn1"/>

</androidx.constraintlayout.widget.ConstraintLayout>

約束佈局下View的寬高0dp 

在ConstraintLayout下 0dp 有一個特別的功能。讓View根據定位屬性填滿高度或者寬度。

例子1

效果圖:

 

 xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.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:background="@color/white"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:id="@+id/btn1"
        android:layout_width="0dp"
        android:layout_height="50dp"
        android:layout_marginTop="20dp"
        android:text="按鍵1"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

效果圖裏可以看到按鍵1的寬度根據定位屬性被填滿了

例子2

效果圖:

 

 xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.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:background="@color/white"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:id="@+id/btn1"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_marginTop="20dp"
        android:text="按鍵1"
        app:layout_constraintBottom_toTopOf="@+id/btn2"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/btn2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="按鍵2"
        android:layout_marginBottom="600dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

 

 

均分屬性 app:layout_constraintHorizontal_chainStyle

 

 

End

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