前言
這篇博客其實拖了很久,原因是我早就已經徹底掌握了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
這裏要介紹一個關鍵字 parent,parent會經常使用。當前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