目錄
前言
ConstraintLayout是目前Android Studio創建一個Activity的默認根佈局。在Android training中也是排在佈局中的第一位,足夠體現重要性。
優點:是可以減少佈局嵌套,彌補四大布局比較不好實現的地方,良好支持拖拽,良好支持UI可視化編輯。
缺點:ConstraintLayout作爲ListView的Item根佈局時設置Item元素可見性,不會觸發onLayout,位置不更新。與傳統列表結合使用,要慎重考慮。
本文以代碼結合可視化UI編輯方式說明
1.將ConstraintLayout添加到項目中
1.1在module的build.gradle添加如下依賴
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
1.2在Project的build.gradle添加如下依賴
repositories {
google()
jcenter()
}
1.3在工具欄或同步通知中,點擊 Sync Project with Gradle Files
注:如果sync 失敗需要重複試幾次
1.4將跟佈局替換成 androidx.constraintlayout.widget.ConstraintLayout
2.基本規則
2.1每個控件至少要兩個約束條件:一個水平約束,一個垂直約束。
水平約束:
layout_constraintLeft_toLeftOf
layout_constraintLeft_toRightOf
layout_constraintRight_toLeftOf
layout_constraintRight_toRightOf
layout_constraintBaseline_toBaselineOf
layout_constraintStart_toEndOf
layout_constraintStart_toStartOf
layout_constraintEnd_toStartOf
layout_constraintEnd_toEndOf
垂直約束
layout_constraintTop_toTopOf
layout_constraintTop_toBottomOf
layout_constraintBottom_toTopOf
layout_constraintBottom_toBottomOf
2.2、無法將 match_parent
用於 ConstraintLayout
中的任何視圖。請改用0dp即
“match constraints” 。
3.示例講解
3.1居中對齊
圖1.1
3.1.1 頂部居中對齊
如圖1.1中的“頂部居中按鈕”
3.1.1.1代碼實現
<Button
android:id="@+id/btn_center_top"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="80dp"
android:text="頂部居中按鈕"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tv_title" />
基於屏幕左右居中關鍵代碼:
控件左側約束到屏幕父佈局的左側
app:layout_constraintStart_toStartOf="parent"
控件右側約束到屏幕右側
app:layout_constraintEnd_toEndOf="parent"
控件頂部約束到tv_title的底部
app:layout_constraintTop_toBottomOf="@+id/tv_title"
3.1.1.2可視化編輯實現
從Palette中左鍵選中Button直接拖到界面中,放在頂部標題文字下,在可視化界面左鍵選中Button,即可看到右邊的Attribute面板,如圖1.2。點擊左右兩個藍色加號按鈕,設置0,點擊頂部藍色按鈕設置80,這樣設置完就可以自動生成上面三個約束的代碼和marginTop。
圖1.2
3.1.2 居於父容器正中間對齊
如圖1.1中的“屏幕居中按鈕”
3.1.2.1 代碼實現
<Button
android:id="@+id/button3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="屏幕居中按鈕"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
相對頂部居中多了一行底部約束到父容器底部
app:layout_constraintBottom_toBottomOf="parent"
另外 app:layout_constraintHorizontal_bias="0.5" 是基於父容器左右對齊,拖拽自動生成,可以去掉,後面會本章後面會說明。
3.1.2.2可視化編輯實現
左右兩邊點擊兩個藍色加號並設置0間距,如果頂部和底部沒有其他控件遮擋,可以點擊上下兩個藍色加號,設置0間距即可,如圖1.3。如果頂部和底部有其他空間就需要在Design可視化界面,選中空間頂部圓點拖到父容器頂部,生成約束線即成功,底部同理,如圖1.4。關於具體操作視頻,文章底部有官網文章有操作視頻可以參考。
圖1.3 圖1.4
3.1.3 居於上下控件居中
如圖1.1中的“居於上下控件居中”按鈕
3.1.3.1 代碼實現
<Button
android:id="@+id/btn_center_custom"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="基於上下控件居中"
app:layout_constraintBottom_toTopOf="@+id/btn_bottom_center"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/button3" />
3.1.3.2 可視化編輯實現
如圖1.5 將Button拖到上下兩個按鈕中間,選中按鈕,然後再Attributes的layout面板中點擊上下左右藍色加號並設置0間距。
圖 1.5
3.2 排列
圖 1.6
3.2.1 代碼實現
底部三個按鈕的底部約束到父容器底部,左右兩側分別約束到左右兩側最近的控件,左側沒有控件就約束到父容器左側如“底部2”的 app:layout_constraintStart_toStartOf="parent" ,右側沒有控件就約束到app:layout_constraintRight_toEndof="parent" ;
倒數第二行,“底部4”按鈕底部約束到“底部2”按鈕,“底部5”和“底部6”按鈕分別基線對其左側的控件,即文字保持在同一水平線,如app:layout_constraintBaseline_toBaselineOf 屬性。
編輯框和按鈕填滿橫向佈局的情況,“Button”約束到父容器右側;“Name”編輯框設置 android:layout_width="0dp",右側約束到“Button”左側,左側約束到父容器左側。
<?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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ArrangeActivity">
<TextView
android:id="@+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="排列示例"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/btn_bottom_center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="38dp"
android:text="底部1"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/btn_bottom_right"
app:layout_constraintStart_toEndOf="@+id/btn_bottom_left" />
<Button
android:id="@+id/btn_bottom_left"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="38dp"
android:text="底部2"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/btn_bottom_center"
app:layout_constraintStart_toStartOf="parent" />
<Button
android:id="@+id/btn_bottom_right"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="38dp"
android:text="底部3"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/btn_bottom_center" />
<Button
android:id="@+id/button5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:text="底部4"
app:layout_constraintBottom_toTopOf="@+id/btn_bottom_left"
app:layout_constraintEnd_toStartOf="@+id/button6"
app:layout_constraintStart_toStartOf="parent" />
<Button
android:id="@+id/button6"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="底部5"
app:layout_constraintEnd_toStartOf="@+id/button7"
app:layout_constraintStart_toEndOf="@+id/button5"
app:layout_constraintBaseline_toBaselineOf="@+id/button5"
/>
<Button
android:id="@+id/button7"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="底部6"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/button6"
app:layout_constraintBaseline_toBaselineOf="@+id/button6"
/>
<Button
android:id="@+id/button8"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:text="Button"
app:layout_constraintBottom_toTopOf="@+id/button7"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/editText" />
<EditText
android:id="@+id/editText"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:ems="10"
android:inputType="textPersonName"
android:text="Name"
app:layout_constraintBaseline_toBaselineOf="@+id/button8"
app:layout_constraintEnd_toStartOf="@+id/button8"
app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
3.2.2 可視化編輯
如圖1.7 ,鼠標左鍵按住圓點拖動到要約束的目標位置即可自動生成約束代碼。基線對齊需要:右鍵點擊要約束的文本視圖,然後點擊Show Baseline就會看到控件內部出現圓角矩形,左鍵按住這個圓角矩形,拖到目標的基線位置(圓角矩形)即可實現基線對齊。在周圍控件正好是要約束的目標控件時,可以直接使用3.1.1.2的方式直接點擊藍色加號按鈕添加約束。
圖1.7
3.3引導線Guideline
引導線用途:
您可以添加垂直或水平約束引導線約束視圖,並且用戶看不到該引導線。
您可以根據相對於佈局邊緣的dp單位或百分比在佈局中定位引導線。
3.3.1 Guideline的關鍵屬性
android:orientation="horizontal" 橫向
android:orientation="vertical" 縱向
app:layout_constraintGuide_percent="0.5" 按父容器比例決定Guideline位置,0.5爲中間位置
app:layout_constraintGuide_begin="157dp" 距離開始位置的距離決定Guideline的位置
app:layout_constraintGuide_end="128dp" 距離結束位置的距離決定Guideline的位置
如果是橫向:開始位置位左邊,結束位置位右邊。如果是縱向:開始位置爲頂部,結束位置位底部。
上面三個決定Guideline位置屬性是互斥的,只能選擇合適的一個。
3.3.2 Guideline的可視化操作
在佈局的xml的Design模式右鍵->Helpers->Add Vertical Guideline或Add Horizontal Guideline即可添加橫向或縱向引導線。如圖1.8
調整定位模式:將鼠標放在引導線邊緣圖標(可能是百分號或實心三角形),點擊即可切換自動切換app:layout_constraintGuide_percent、app:layout_constraintGuide_begin和app:layout_constraintGuide_end。如圖1.9
調整引導線的位置:將鼠標放在引導線上,出現雙向箭頭即可拖拽。如圖2.0
如圖1.8
圖1.9
圖2.0
3.4計算器示例
3.4.1實現邏輯
縱向:從計算結果顯示的TextView到按鈕7、按鈕4、按鈕1和按鈕.都是頂部約束到頂部最近的控件、底部約束到底部最近的控件。
橫向:從左到右,依次左側約束到左側最近的控件,右側約束到右側最近的控件。從左側第二個控件開始底部對齊前一個控件,如圖中的按鈕7、按鈕8和按鈕9。
約束佈局默認添加間距的特性,可以在再橫向和縱向將控件剩餘的控件平均分配到每個控件的間隙。這種默認添加間距的特性可以通過chainStyle改變,下面章節會詳細介紹。
圖2.1
完整實現代碼:
<?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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".CalculatorActivity">
<TextView
android:id="@+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="計算器"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/tv_result"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginLeft="16dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:layout_marginRight="16dp"
android:background="@android:color/darker_gray"
android:text="0"
android:textSize="36sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tv_title" />
<Button
android:id="@+id/btn_7"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="7"
app:layout_constraintBottom_toTopOf="@+id/btn_4"
app:layout_constraintEnd_toStartOf="@+id/btn_8"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tv_result" />
<Button
android:id="@+id/btn_8"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="8"
app:layout_constraintBottom_toBottomOf="@+id/btn_7"
app:layout_constraintEnd_toStartOf="@+id/btn_9"
app:layout_constraintStart_toEndOf="@+id/btn_7" />
<Button
android:id="@+id/btn_9"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="9"
app:layout_constraintBottom_toBottomOf="@+id/btn_8"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/btn_8" />
<Button
android:id="@+id/btn_4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="4"
app:layout_constraintBottom_toTopOf="@+id/btn_1"
app:layout_constraintEnd_toStartOf="@+id/btn_5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/btn_7" />
<Button
android:id="@+id/btn_5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="5"
app:layout_constraintBottom_toBottomOf="@+id/btn_4"
app:layout_constraintEnd_toStartOf="@+id/btn_6"
app:layout_constraintStart_toEndOf="@+id/btn_4" />
<Button
android:id="@+id/btn_6"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="6"
app:layout_constraintBottom_toBottomOf="@+id/btn_5"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/btn_5" />
<Button
android:id="@+id/btn_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="1"
app:layout_constraintBottom_toTopOf="@+id/btn_dot"
app:layout_constraintEnd_toStartOf="@+id/btn_2"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/btn_4" />
<Button
android:id="@+id/btn_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="2"
app:layout_constraintBottom_toBottomOf="@+id/btn_1"
app:layout_constraintEnd_toStartOf="@+id/btn_3"
app:layout_constraintStart_toEndOf="@+id/btn_1" />
<Button
android:id="@+id/btn_3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="3"
app:layout_constraintBottom_toBottomOf="@+id/btn_2"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/btn_2" />
<Button
android:id="@+id/btn_dot"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="."
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/btn_0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/btn_1" />
<Button
android:id="@+id/btn_0"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="0"
app:layout_constraintBottom_toBottomOf="@+id/btn_dot"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/btn_dot" />
</androidx.constraintlayout.widget.ConstraintLayout>
3.4.2計算器的可視化編輯實現可以參照3.1.2.2
3.5寬高比示例
顯示效果如圖2.2
圖2.2
3.5.1 代碼實現
寬高比使用場景:如圖2.2 圖片橫向填滿屏幕,整張圖的比例保持不變。在沒有約束佈局的情況下,需要去計算屏幕的寬度,然後根據要顯示圖片的比例計算出圖片的顯示高度。現在如果父容器是約束佈局,就可以在目標控件設置app:layout_constraintDimensionRatio屬性。
如圖中的大圖就設置了
app:layout_constraintDimensionRatio="h,16:9" 寬比高 16:9
換個屬性值實現同樣的效果:
app:layout_constraintDimensionRatio="w,9:16" 寬比高 16:9
注意1:寬高必須設置0dp
android:layout_width="0dp"
android:layout_height="0dp"
大圖的佈局代碼
<ImageView
android:id="@+id/imageView"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginStart="16dp"
android:layout_marginLeft="16dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:layout_marginRight="16dp"
android:scaleType="centerCrop"
app:layout_constraintDimensionRatio="h,16:9"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tv_title"
app:srcCompat="@drawable/lake"
/>
注意2:設置寬高比的目標控件寬高是可確定的。如圖2.2中安卓機器人圖標的上下左右都需要約束,漏掉一個控件就不能正常顯示。如下面代碼:去掉app:layout_constraintBottom_toBottomOf控件就無法顯示了。
<ImageButton
android:id="@+id/imageButton"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginLeft="16dp"
android:layout_marginTop="16dp"
app:layout_constraintBottom_toBottomOf="@+id/textView4"
app:layout_constraintDimensionRatio="h,1:1"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="@+id/textView3"
app:layout_constraintTop_toBottomOf="@+id/imageView"
app:srcCompat="@mipmap/ic_launcher" />
3.5.2 寬高比可視化編輯實現
首先將寬高設置0dp,然後在佈局的Design選中目標控件,就可以在Arrtibutes面板的Layout類別中看到控件正方形左上角多了一個內三角形如圖2.3,單擊即可默認實現1:1比例。如圖2.4。設置ratio比例內容即可。
圖2.3
圖2.4
3.6Chains鏈模式示例
顯示效果如圖2.5
圖2.5
3.6.1設置Chain鏈模式關鍵要點
1、關鍵屬性
app:layout_constraintHorizontal_chainStyle 只需要設置排列的第一個,如圖2.5中只有按鈕1、按鈕4和按鈕7設置了該屬性。
2、屬性值效果
spread 如圖2.5中的按鈕1、按鈕2和按鈕3。另外這也是缺省值。沒有設置上述屬性也是spread的效果。
spread_inside 如圖2.5中的按鈕4、按鈕5和按鈕6。第一個和最後一個與父容器沒有間距。排列的控件之間有間距。
packed 如圖2.5中的按鈕7、按鈕8和按鈕9。第一個和最後一個與父容器有間距。排列的控件之間無間距。
完整代碼:
<?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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ChainsActivity">
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="Chains示例"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/btn_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="按鈕1"
app:layout_constraintEnd_toStartOf="@+id/btn_2"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintHorizontal_chainStyle="spread"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView5" />
<Button
android:id="@+id/btn_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="按鈕2"
app:layout_constraintBaseline_toBaselineOf="@+id/btn_1"
app:layout_constraintEnd_toStartOf="@+id/btn_3"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/btn_1" />
<Button
android:id="@+id/btn_3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="按鈕3"
app:layout_constraintBaseline_toBaselineOf="@+id/btn_2"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/btn_2" />
<Button
android:id="@+id/btn_4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="按鈕4"
app:layout_constraintEnd_toStartOf="@+id/btn_5"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintHorizontal_chainStyle="spread_inside"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView6" />
<Button
android:id="@+id/btn_5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="按鈕5"
app:layout_constraintBaseline_toBaselineOf="@+id/btn_4"
app:layout_constraintEnd_toStartOf="@+id/btn_6"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/btn_4" />
<Button
android:id="@+id/btn_8"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="按鈕8"
app:layout_constraintBaseline_toBaselineOf="@+id/btn_7"
app:layout_constraintEnd_toStartOf="@+id/btn_9"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/btn_7" />
<Button
android:id="@+id/btn_9"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="按鈕9"
app:layout_constraintBaseline_toBaselineOf="@+id/btn_8"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/btn_8" />
<Button
android:id="@+id/btn_6"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="按鈕6"
app:layout_constraintBaseline_toBaselineOf="@+id/btn_5"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/btn_5" />
<Button
android:id="@+id/btn_7"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="按鈕7"
app:layout_constraintEnd_toStartOf="@+id/btn_8"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView7" />
<TextView
android:id="@+id/textView5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginLeft="16dp"
android:layout_marginTop="148dp"
android:text="spread"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/textView6"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginLeft="16dp"
android:layout_marginTop="32dp"
android:text="spread_inside"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/btn_1" />
<TextView
android:id="@+id/textView7"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginLeft="16dp"
android:layout_marginTop="32dp"
android:text=" packed"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/btn_4" />
</androidx.constraintlayout.widget.ConstraintLayout>
3.6.1實現Chain模式可視化編輯
在佈局中右鍵選中排列中的任意控件->Cycle Chain mode 如圖2.6,即可實現ChainMode在spread、spread_inside和packed切換。
圖2.6
3.7Barrier屏障示例
屏障顧名思義就是將一堆控件擋住。要擋在哪個方向是可以設置的。
圖2.7
3.7.1代碼實現Barrier屏障
往佈局中添加
androidx.constraintlayout.widget.Barrier控件
設置app:barrierDirection屏障方向屬性,這個值是相對於被屏障擋住控件的。可選值:left、right、top、bottom、start、end。
參考:
https://developer.android.google.cn/training/constraint-layout
https://developer.android.google.cn/reference/androidx/constraintlayout/widget/ConstraintLayout