無比強大的ViewGroup——ConstraintLayout

ConstraintLayout是一種可以靈活的控制view大小和權重的view容器涌攻。

支持Android Api 9以上

目前它有以下的約束方式:

  1. Relative positioning相對位置約束
  2. Margins間距約束
  3. Centering positioning 中心約束
  4. Circular positioning 圓形約束
  5. Dimension constraints 尺寸約束
  6. Chains 鏈式約束
  7. Virtual Helpers objects 虛擬幫助對象
  8. 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>

得到的效果如下圖:

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消失的導致的“位移”泛啸。

ViewB GONE 之前
ViewB GONE 之后

下面是代碼實現(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]
ConstraintLayout

那么來看下下圖中的效果是如何實現(xiàn)的录豺。

ConstraintLayout
<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中:

  1. 相當與將控件的大小縮小成為一個點双饥,它的寬和高約等于0
  2. 它與其它控件的依賴關系是依然存在的,但是自身的margin是幾乎等于0的

Dimensions constraints

尺寸約束弟断,同其它ViewGroup一樣對控件的寬和高給出最大值和最小值咏花。對應的屬性值如下:

  • android:minWidth
  • android:minHeight
  • android:maxWidth
  • android:maxHeight

上面的屬性,在控件申明為wrap_content有效

Widgets dimension constraints

控件可以通過android:layout_widthandroid:layout_height設置自己的大小阀趴,這兩個屬性的值三種情況:

  1. 使用具體確定的數(shù)值昏翰,或者是資源xml中定義的具體尺寸.
  2. 使用WRAP_CONTENT,會自行計算大小
  3. 使用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" />

寬和高之比可以用下面兩種方式:

  1. 一個float數(shù)值苟耻,其等于寬/高的值
  2. 使用比例篇恒,例如:“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)一管理腾么。成為鏈的條件是:一組控件他們通過一個雙向的約束關系鏈接起來

ConstraintLayout.jpg

注意:鏈的屬性是由一條鏈的頭結點控制的杈湾。而頭結點的定義是一條鏈中位于最左端的控件解虱。

ConstraintLayout

鏈的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ù)所設置的比重來分配剩下的空間糖埋。

ConstraintLayout

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"

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末哥遮,一起剝皮案震驚了整個濱河市岂丘,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌眠饮,老刑警劉巖奥帘,帶你破解...
    沈念sama閱讀 211,743評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異仪召,居然都是意外死亡寨蹋,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,296評論 3 385
  • 文/潘曉璐 我一進店門扔茅,熙熙樓的掌柜王于貴愁眉苦臉地迎上來已旧,“玉大人,你說我怎么就攤上這事召娜≡送剩” “怎么了?”我有些...
    開封第一講書人閱讀 157,285評論 0 348
  • 文/不壞的土叔 我叫張陵玖瘸,是天一觀的道長秸讹。 經(jīng)常有香客問我,道長雅倒,這世上最難降的妖魔是什么璃诀? 我笑而不...
    開封第一講書人閱讀 56,485評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮蔑匣,結果婚禮上劣欢,老公的妹妹穿的比我還像新娘棕诵。我一直安慰自己,他們只是感情好氧秘,可當我...
    茶點故事閱讀 65,581評論 6 386
  • 文/花漫 我一把揭開白布年鸳。 她就那樣靜靜地躺著,像睡著了一般丸相。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上彼棍,一...
    開封第一講書人閱讀 49,821評論 1 290
  • 那天灭忠,我揣著相機與錄音,去河邊找鬼座硕。 笑死弛作,一個胖子當著我的面吹牛,可吹牛的內容都是我干的华匾。 我是一名探鬼主播映琳,決...
    沈念sama閱讀 38,960評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼蜘拉!你這毒婦竟也來了萨西?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 37,719評論 0 266
  • 序言:老撾萬榮一對情侶失蹤旭旭,失蹤者是張志新(化名)和其女友劉穎谎脯,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體持寄,經(jīng)...
    沈念sama閱讀 44,186評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡源梭,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,516評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了稍味。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片废麻。...
    茶點故事閱讀 38,650評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖模庐,靈堂內的尸體忽然破棺而出烛愧,到底是詐尸還是另有隱情,我是刑警寧澤赖欣,帶...
    沈念sama閱讀 34,329評論 4 330
  • 正文 年R本政府宣布屑彻,位于F島的核電站,受9級特大地震影響顶吮,放射性物質發(fā)生泄漏社牲。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,936評論 3 313
  • 文/蒙蒙 一悴了、第九天 我趴在偏房一處隱蔽的房頂上張望搏恤。 院中可真熱鬧违寿,春花似錦、人聲如沸熟空。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,757評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽息罗。三九已至掂咒,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間迈喉,已是汗流浹背绍刮。 一陣腳步聲響...
    開封第一講書人閱讀 31,991評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留挨摸,地道東北人孩革。 一個月前我還...
    沈念sama閱讀 46,370評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像得运,于是被迫代替她去往敵國和親膝蜈。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,527評論 2 349

推薦閱讀更多精彩內容