ConstraintLayout
是一種可以靈活的控制view大小和權重的view容器涌攻。
支持Android Api 9以上
目前它有以下的約束方式:
- Relative positioning相對位置約束
- Margins間距約束
- Centering positioning 中心約束
- Circular positioning 圓形約束
- Dimension constraints 尺寸約束
- Chains 鏈式約束
- Virtual Helpers objects 虛擬幫助對象
- Optimizer 優(yōu)化
Relative positioning
相對位置約束是指布局中view相對于其它view的位置來設置自己的位置达皿。分為縱向和橫向兩種:
- 橫向: left, right, start, end
一般情況下熙宇,View開始部分就是左邊秫逝,但是有的語言目前為止還是按照從右往左的順序來書寫的,例如阿拉伯語,在Android 4.2系統(tǒng)之后竹捉,Google在Android中引入了RTL布局,更好了支持了由右到左文字布局的顯示尚骄,為了更好的兼容RTL布局块差,google推薦使用MarginStart和MarginEnd來替代MarginLeft和MarginRight,這樣應用可以在正常的屏幕和由右到左顯示文字的屏幕上都保持一致的用戶體驗。
- 縱向:top, bottom, text baseline
下面舉個示例:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<include
layout="@layout/view_title_bar"
android:id="@+id/view_title"/>
<TextView
android:id="@+id/tv_one"
android:text="ViewA"
······
app:layout_constraintTop_toBottomOf="@id/view_title"
······
/>
<TextView
android:text="ViewB"
······
app:layout_constraintTop_toBottomOf="@id/tv_one"
······
/>
</android.support.constraint.ConstraintLayout>
得到的效果如下圖:
除此之外憨闰,它還有一下的幾種相對約束條件:
- 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
Margins
同其它ViewGroup
一樣状蜗,它也有Margins
約束條件,不同的是當參照控件可見性為GONE的時候又多了一些其它的屬性鹉动。舉個例子轧坎,當A控件 約束 在B控件的左邊酷誓,B控件GONE了语卤,此時A會額外擁有一個margin的能力,來“補充”B消失的導致的“位移”泛啸。
下面是代碼實現(xiàn):
<TextView
······
android:id="@+id/tv_B"
android:layout_width="100dp"
android:text="ViewB"
app:layout_constraintLeft_toRightOf="parent"
android:visibility="visible"
/>
<TextView
······
android:id="@+id/tv_D"
android:text="ViewD"
app:layout_goneMarginLeft="120dp"
android:layout_marginLeft="20dp"
app:layout_constraintLeft_toRightOf="@id/tv_B"
/>
下面羅列一下它的約束條件:
- android:layout_marginStart
- android:layout_marginEnd
- android:layout_marginLeft
- android:layout_marginTop
- android:layout_marginRight
- android:layout_marginBottom
- layout_goneMarginStart
- layout_goneMarginEnd
- layout_goneMarginLeft
- layout_goneMarginTop
- layout_goneMarginRight
- layout_goneMarginBottom
Centering positioning and bias
我們如何使控件居中呢边琉?
這里我們先來看看如何讓控件在容器中水平居中属百。
<TextView
android:id="@+id/tv_A"
······
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
······ />
是就是這么奇妙,這樣控件就在容器中水平居中了变姨,垂直居中同理族扰。那么如果是兩個控件中間且居中呢?
直接上代碼:
<TextView
android:id="@+id/tv_B"
android:text="ViewB"
······/>
<TextView
android:id="@+id/tv_C"
android:text="ViewC"
······
app:layout_constraintRight_toLeftOf="parent"
/>
<TextView
android:id="@+id/tv_D"
android:text="ViewD"
······
app:layout_constraintLeft_toLeftOf="@id/tv_B"
app:layout_constraintRiht_toRightOf="@id/tv_C"
/>
只要使得ViewD分別于ViewB和ViewC產生依賴定欧,只要就居中了渔呵。
控件就某一方向不居中的情況
比如使得ViewA距左邊30%而不是50%
<TextView
android:id="@+id/tv_A"
······
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintHorizontal_bias="0.3"
······ />
當屏幕的尺寸變化時,這種方式能很好的兼容砍鸠。
Circular positioning (Added in 1.1)
在1.1版本中添加了扩氢,圓形約束條件。下面是其相關的屬性:
- layout_constraintCircle : 參照widget的id
- layout_constraintCircleRadius : 中心點距離參照widget中心的距離
- layout_constraintCircleAngle : 角度爷辱,取值范圍[0,360]
那么來看下下圖中的效果是如何實現(xiàn)的录豺。
<Button android:id="@+id/buttonA" ... />
<Button android:id="@+id/buttonB" ...
app:layout_constraintCircle="@+id/buttonA"
app:layout_constraintCircleRadius="100dp"
app:layout_constraintCircleAngle="45" />
Visibility behavior
可見性約束,GONE
通常來講是不會展示在頁面上的饭弓,但是在ConstraintLayout中:
- 相當與將控件的大小縮小成為一個點双饥,它的寬和高約等于0
- 它與其它控件的依賴關系是依然存在的,但是自身的margin是幾乎等于0的
Dimensions constraints
尺寸約束弟断,同其它ViewGroup一樣對控件的寬和高給出最大值和最小值咏花。對應的屬性值如下:
- android:minWidth
- android:minHeight
- android:maxWidth
- android:maxHeight
上面的屬性,在控件申明為wrap_content
有效
Widgets dimension constraints
控件可以通過android:layout_width
和android:layout_height
設置自己的大小阀趴,這兩個屬性的值三種情況:
- 使用具體確定的數(shù)值昏翰,或者是資源xml中定義的具體尺寸.
- 使用
WRAP_CONTENT
,會自行計算大小 - 使用0dp, 其效果等同于
MATCH_CONSTRAINT
需要注意的是:
MATCH_PARENT
在ConstraintLayout不推薦使用×跫保可以將控件的left/right
矩父、top/bottom
約束于parent。
WRAP_CONTENT(1.1)
在ConstraintLayout中排霉,仍然可以對WRAP_CONTENT的最大尺寸進行約束:
- app:layout_constrainedWidth=”true|false”
app:layout_constrainedHeight=”true|false”
當其中一個被設置為true時,控件的最大寬高任然可以被約束鏈約束,需要注意的是攻柠,這樣做會使布局變慢一些球订。
MATCH_CONSTRAINT(1.1)
當寬高被設為MATCH_CONSTRAINT,這個控件將嘗試占據(jù)布局上所有可用的地方瑰钮,但同時會被這些屬性所限制:
- layout_constraintWidth_min/layout_constraintHeight_min:最小寬高
layout_constraintWidth_max/layout_constraintHeight_max:最大寬高
layout_constraintWidth_percent/layout_constraintHeight_percent:寬高相對于父容器的百分比冒滩。
注意:這些屬性同時可以設置為wrap;
當使用百分比尺寸的時候浪谴,應當設置寬高為MATCH_CONSTRAINT开睡;
父容器需要設置app:layout_constraintWidth_default=”percent”或app:layout_constraintHeight_default=”percent”(在1.1-beta2以后不再必須設置)
設置比例
constraintLayout支持子控件設置其寬高比,要使該特性生效至少需要將寬高中的一個設置為0dp(MATCH_CONSTRAINT)
<Button
······
android:layout_width="wrap_content"
android:layout_height="0dp"
app:layout_constraintDimensionRatio="1:1" />
寬和高之比可以用下面兩種方式:
- 一個float數(shù)值苟耻,其等于寬/高的值
- 使用比例篇恒,例如:“2:1”
注意:當寬高均被設為0dp時,父容器將嘗試在滿足所有約束條件及比例的同時凶杖,占據(jù)最大的寬高胁艰;
如果只想對某個方向設置比例,則可以在屬性前面加上W或H智蝠,與比例以,隔開:
<Button android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintDimensionRatio="H,16:9"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
Chains
鏈使我們能夠對一組在水平或豎直方向互相關聯(lián)的控件的屬性進行統(tǒng)一管理腾么。成為鏈的條件是:一組控件他們通過一個雙向的約束關系鏈接起來。
注意:鏈的屬性是由一條鏈的頭結點控制的杈湾。而頭結點的定義是一條鏈中位于最左端的控件解虱。
鏈的Margins
ConstraintLayout支持對鏈添加Margin,如果這條鏈的控件是分散分布的漆撞,將會從已分配給鏈的空間中減去設置的鏈邊距殴泰。
鏈的Style
鏈支持設置他們的Style,只需在頭結點指定layout_constraintHorizontal_chainStyle或layout_constraintVertical_chainStyle。共支持五種類型:
CHAIN_SPREAD(默認值):鏈中的元素將分散分布叫挟;
Weighted chain:在CHAIN_SPREAD模式中艰匙,如果某些組件被設置成MATCH_CONSTRAINT,他們將會占據(jù)所有空余空間并分散分布抹恳;
CHAIN_SPREAD_INSIDE:類似于CHAIN_SPREAD员凝,但鏈的兩端不會分散;
CHAIN_PACKED:鏈中的元素將會緊密相連在一起奋献,偏移(bias)的設定將會影響他們在容器中所處的位置
Weighted chains:當鏈處在默認的模式(CHAIN_SPREAD)且其中一個或多個元素被設置為MATCH_CONSTRAINT時健霹,他們將平均占據(jù)剩下的空余空間;如果其中的結點同時設置了
layout_constraintHorizontal_weight或layout_constraintVertical_weight屬性瓶蚂,那么他們將根據(jù)所設置的比重來分配剩下的空間糖埋。
Virtual Helper objects
虛擬輔助類部件它們最終不會在界面上呈現(xiàn)出來,但可以幫助我們更好更精細地控制布局窃这。目前瞳别。所支持的這類部件包括:
1. Guideline
Guideline可以放在豎直方向或水平方向,水平Guideline的高為0,寬度與父容器一致祟敛;豎直Guideline同理疤坝。
Guideline 具有三類特殊的屬性:
layout_constraintGuide_begin:設置Guideline 距離父容器起始位置的距離(left或top);
layout_constraintGuide_end:設置Guideline 距離父容器尾部的距離(right或bottom);
layout_constraintGuide_percent:設置Guideline 相對于父容器寬度/高度的百分比位置。
2. Barrier(1.1)
Barrier 使用多個控件作為參考馆铁,在這些控件中跑揉,選取在特定方向最邊緣的的控件創(chuàng)建一條Guideline。
constraint_referenced_ids用來設置要參考的控件id,多個控件id間以逗號的形式隔開埠巨。
3. Group(1.1)
Group 用于控制所引用的一組控件的可見性(Visibility)历谍,constraint_referenced_ids用來設置要參考的控件id,多個控件id間以逗號的形式隔開。
<android.support.constraint.Group
android:id="@+id/group"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="visible"
app:constraint_referenced_ids="button4,button9" />
注意:多個Group 部件可以引用相同的控件辣垒,這時Group 在xml中的定義順序將決定這個控件最終的可見性望侈。
Optimizer(1.1)
在1.1 版本中放出了ConstraintLayout的優(yōu)化模式≌Ч梗可以通過設置app:layout_optimizationLevel
的優(yōu)化等級甜无,有以下值:
- none : 無優(yōu)化
- standard : 默認優(yōu)化. 只優(yōu)化direct和barrier
- direct :
- barrier :
- chain : 優(yōu)化鏈式
- dimensions : 優(yōu)化尺寸測量 (experimental), 減少測量度量
以上優(yōu)化的屬性默認是關閉的,可以同時開啟多個如:app:layout_optimizationLevel="direct|barrier|chain"