ConstraintLayout 是 Android Studio 2.2 中主要的新增功能之一敬肚,也是 Google 在2016 年的 I/O 大會上重點宣傳的一個功能毕荐。ConstraintLayout 是使用約束的方式來指定各個控件的位置和關(guān)系的,相比 RelativeLayout 和 LineatLayout 具有更強的特性艳馒,可以減少布局之間的嵌套憎亚。
1. 添加 ConstraintLayout
在工程app目錄下的 build.gradle 添加如下:
dependencies {
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
}
2. 相對位置屬性
layout_constraint[自身控件位置]_[目標控件位置]="[目標控件ID]"员寇,如果id是父布局的id,可以使用parent
<Button android:id="@+id/buttonA" ... />
<Button android:id="@+id/buttonB" ...
app:layout_constraintLeft_toRightOf="@+id/buttonA" />
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
3. Margin屬性
android:layout_marginStart
android:layout_marginEnd
android:layout_marginLeft
android:layout_marginTop
android:layout_marginRight
android:layout_marginBottom
4. goneMargin屬性
goneMargin屬性是指目標控件GONE掉之后第美,自身控件可以設(shè)置個margin值蝶锋。不過margin的方向需要和控件的相對位置的方向保持一致。
假設(shè)我們有這樣一個需求:A設(shè)置為gone后什往,B需要距離父布局的左側(cè)200dp扳缕,怎么辦?這時候别威,goneMargin屬性就派上用場啦躯舔,只要設(shè)置B的layout_goneMarginLeft=200dp即可。這樣省古,A為gone時粥庄,B距離父布局左側(cè)200dp。
layout_goneMarginStart
layout_goneMarginEnd
layout_goneMarginLeft
layout_goneMarginTop
layout_goneMarginRight
layout_goneMarginBottom
5. Bias屬性
bias屬性是指在對齊父容器后豺妓,設(shè)置水平與豎直的比例飒赃。bias支持的屬性如下:
layout_constraintHorizontal_bias
layout_constraintVertical_bias
<androidx.constraintlayout.widget.ConstraintLayout ...>
<Button android:id="@+id/button" ...
app:layout_constraintHorizontal_bias="0.3"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent/>
</>
6. Ratio屬性
layout_constraintDimensionRatio,通過該屬性可以設(shè)置View的高寬比蔫慧。
<?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"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!--指定高度姑躲,寬度隨著寬高比自適應(yīng) -->
<!--app:layout_constraintDimensionRatio="16:9" W: 默認盟蚣,表示寬高比-->
<TextView
android:id="@+id/text_01"
android:layout_width="0dp"
android:layout_height="60dp"
android:background="#B0E46E"
android:text="text_01"
app:layout_constraintDimensionRatio="16:9"
app:layout_constraintLeft_toLeftOf="parent" />
<!--指定高度,寬度隨著寬高比自適應(yīng) -->
<!--app:layout_constraintDimensionRatio="H,16:9" H: 表示高寬比-->
<TextView
android:id="@+id/text_02"
android:layout_width="0dp"
android:layout_height="60dp"
android:background="#AA4727"
android:text="text_02"
app:layout_constraintDimensionRatio="H,16:9"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@+id/text_01" />
<!--指定寬度阐枣,按照寬度來計算高寬比蔼两,默認是寬高比 -->
<TextView
android:id="@+id/text_03"
android:layout_width="60dp"
android:layout_height="0dp"
android:background="#F6BE4F"
android:text="text_03"
app:layout_constraintDimensionRatio="16:9"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@+id/text_02" />
<!--指定寬度额划,按照寬度來計算高寬比 W:表示高寬比 -->
<TextView
android:id="@+id/text_04"
android:layout_width="60dp"
android:layout_height="0dp"
android:background="#CA4B45"
android:text="text_04"
app:layout_constraintDimensionRatio="W,16:9"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@+id/text_03" />
<!--android:layout_width="0dp" 0dp表示充滿父控件或說是充滿其余空間-->
<TextView
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#CFDEF9"
android:text="text_05"
app:layout_constraintDimensionRatio="3"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/text_04" />
</androidx.constraintlayout.widget.ConstraintLayout>
運行圖俊戳,如下:
7. Chains 鏈狀結(jié)構(gòu)
如下圖:
要想Chain Style生效燥滑,必須設(shè)置當(dāng)前鏈方向的邊為wrap_content突倍,比如上面的水平鏈盆昙,寬設(shè)為wrap_content淡喜。還有就是控件要相互引用炼团,比如A的右邊依賴B的左邊疏尿,B的左邊依賴A的右邊褥琐。
Chain Style 設(shè)置在第一個控件上 。
屬性有兩個:
layout_constraintHorizontal_chainStyle
layout_constraintVertical_chainStyle
支持的值有三個:
CHAIN_SPREAD:均勻分布控件。
CHAIN_SPREAD_INSIDE磕洪,同上析显,但是邊上的控件不均勻分布。
CHAIN_PACKED:控件緊挨在一起浑侥,還可以通過bias屬性設(shè)置偏移量寓落。
Weighted chains:
app:layout_constraintHorizontal_weight
app:layout_constraintVertical_weight
跟線性布局的weight差不多伶选,layout_constraintHorizontal_weight需要設(shè)置width=0dp,控件的大小根據(jù)設(shè)置的weight比例進行設(shè)置割坠。
<?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"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/tv_bottom_01"
android:layout_width="0dp"
android:layout_height="56dp"
android:background="#F67"
android:gravity="center"
android:text="首頁"
android:textColor="#FFFFFF"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintHorizontal_chainStyle="spread"
app:layout_constraintHorizontal_weight="1"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="@+id/tv_bottom_02" />
<TextView
android:id="@+id/tv_bottom_02"
android:layout_width="0dp"
android:layout_height="56dp"
android:background="#A67"
android:gravity="center"
android:text="圈子"
android:textColor="#FFFFFF"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintHorizontal_weight="1"
app:layout_constraintLeft_toRightOf="@+id/tv_bottom_01"
app:layout_constraintRight_toLeftOf="@+id/tv_bottom_03" />
<TextView
android:id="@+id/tv_bottom_03"
android:layout_width="0dp"
android:layout_height="56dp"
android:background="#767"
android:gravity="center"
android:text="我的"
android:textColor="#FFFFFF"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintHorizontal_weight="1"
app:layout_constraintLeft_toRightOf="@id/tv_bottom_02"
app:layout_constraintRight_toRightOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
運行圖,如下:
8. Guideline
android.support.constraint.Guideline
該類比較簡單己单,主要用于輔助布局纹笼,即類似為輔助線廷痘,橫向的件已、縱向的篷扩。該布局是不會顯示到界面上的。
所以其有個屬性為:
android:orientation="vertical"
android:orientation="horizontal"
除此以外厦滤,還差個屬性掏导,決定該輔助線的位置:
layout_constraintGuide_begin
layout_constraintGuide_end
layout_constraintGuide_percent
可以通過上面3個屬性其中之一來確定屬性值位置趟咆。
begin=30dp值纱,即可認為距離頂部30dp的地方有個輔助線坯汤,根據(jù)orientation來決定是橫向還是縱向惰聂。
end=30dp咱筛,即為距離底部迅箩。
percent=0.8即為距離頂部80%饲趋。
比如:有個按鈕撤蟆,決定通過兩根輔助線來定位枫疆,一根橫向距離底部80%敷鸦,一個縱向距離頂部80%扒披,按鈕就定位在他們交叉的地方。
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.constraint.Guideline
android:id="@+id/guideline_h"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.8" />
<android.support.constraint.Guideline
android:id="@+id/guideline_w"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.8" />
<TextView
android:layout_width="60dp"
android:layout_height="60dp"
android:background="#612"
app:layout_constraintLeft_toRightOf="@id/guideline_w"
app:layout_constraintTop_toBottomOf="@id/guideline_h" />
</androidx.constraintlayout.widget.ConstraintLayout>
運行圖,如下:
- 注意ConstraintLayout不支持match_parent屬性辆亏,要用0dp代替扮叨,在加上設(shè)置特性的約束屬性领迈,即可實現(xiàn)match_parent的效果狸捅。