Android ConstraintLayout 使用詳解

Android在遇到復(fù)雜布局的時(shí)候骗奖,避免不了嵌套布局,渲染起來(lái)也影響了應(yīng)用的性能氢烘,而且在維護(hù)的時(shí)候會(huì)有些煩躁,至少我是這樣家厌,還有百分比等播玖,這時(shí)我們的 ConstraintLayout 就是為了解決這些問題而來(lái)的,況且還兼容到API 9饭于,更沒有理由了蜀踏。所以這篇用法就應(yīng)運(yùn)而生了,畢竟優(yōu)秀的東西總是讓人向往镰绎。(本文不講解拖拽用法)

官方文檔 https://developer.android.com/reference/android/support/constraint/ConstraintLayout

(一)基本屬性
layout_constraintLeft_toRightOf
layout_constraintRight_toLeftOf
layout_constraintLeft_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

可以看到每個(gè)屬性上有兩個(gè)方向脓斩,可以看第一個(gè)就是 Left -> Right,表示當(dāng)前添加到視圖控件以什么相對(duì)位置進(jìn)行擺放畴栖。通俗的講就是你告訴我我以誰(shuí)為基準(zhǔn)來(lái)擺放我自己随静。

image.png
 <Button
    android:id="@+id/button17"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Button17"
    />
<Button
    android:id="@+id/button16"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Button16"
    app:layout_constraintLeft_toRightOf="@id/button17"
     />

以上的例子,換成剛才的說法就是,添加button16的時(shí)候燎猛,以我button16的左側(cè)邊去對(duì)應(yīng)button17的右側(cè)邊恋捆。
可能有人會(huì)說那Start和End呢?相關(guān)Start和End的下面4個(gè)屬性我覺得等同于左右重绷。我查了一下說是有的語(yǔ)言是從右向左書寫的沸停。所以用Start和End能兼容兩種形式。官方推薦使用Start和End昭卓。

layout_constraintBaseline_toBaselineOf相當(dāng)于文字基準(zhǔn)線對(duì)齊愤钾,什么是基準(zhǔn)線呢?也就是相當(dāng)于文字的下劃線的位置的一條虛線候醒。

以上的屬性有一點(diǎn)特殊的是所有的值不僅可以設(shè)置為控件id能颁,也就是根據(jù)id擺放,也可以對(duì)父容器進(jìn)行擺放倒淫,也就是ConstraintLayout伙菊。這時(shí)候設(shè)置值為parent。

<Button
    android:id="@+id/buttonA"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Button-A"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constraintTop_toTopOf="parent" />
6B95D046-1223-42B5-848D-2B54AB5513FE.png

可以看到在所有的方向都指向parent敌土,ButtonA全屏居中了镜硕。因?yàn)锽uttonA的四個(gè)邊相對(duì)了父容器的四個(gè)邊擺放。如果四根彈簧當(dāng)失去橫向或者縱向的兩根則變成了水平居中或者垂直居中返干。

再看外邊距的幾個(gè)屬性:
android:layout_marginStart
android:layout_marginEnd
android:layout_marginLeft
android:layout_marginTop
android:layout_marginRight
android:layout_marginBottom

這些跟其他布局的外邊距一樣兴枯,但是如果沒有約束關(guān)系,也就是鏈條連接犬金,設(shè)置這個(gè)屬性是無(wú)效的念恍。原因可能是ConstraintLayout沒有約束關(guān)系,就沒必要用ConstraintLayout了吧晚顷,這可能是個(gè)冷知識(shí)峰伙。

繼續(xù)看一個(gè)有特色的外邊距:
layout_goneMarginStart
layout_goneMarginEnd
layout_goneMarginLeft
layout_goneMarginTop
layout_goneMarginRight
layout_goneMarginBottom

也就是說在約束目標(biāo)控件為Gone的時(shí)候,要不要來(lái)點(diǎn)邊距该默。例如我們?cè)诰€性布局中瞳氓,如果三個(gè)按鈕按水平擺放。中間的設(shè)置為Gone后栓袖,兩邊的控件會(huì)貼在一起匣摘。完全隱藏了。沒有設(shè)置邊距平滑的機(jī)會(huì)裹刮。而這個(gè)外邊距就是在目標(biāo)約束組件設(shè)置為Gone的時(shí)候才會(huì)出現(xiàn)的邊距音榜。下面會(huì)舉例子。

相關(guān)基礎(chǔ)的ConstraintLayout用法已經(jīng)介紹完了捧弃,簡(jiǎn)單的練習(xí)一下吧赠叼,寫一個(gè)樣例擦囊,先看一下效果圖:


1745E0DD-7845-4BA7-8A47-7CB2A8734229.png

中間的是各種相對(duì)關(guān)系的例子,上面是layout_goneMarginLeft屬性的例子嘴办,上面的例子是有兩個(gè)Button瞬场,我隱藏了一個(gè),本身是沒有間距的涧郊,從圖中可以看出來(lái)出現(xiàn)了間距贯被。然后看一下布局的完整代碼。

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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">


<Button
    android:id="@+id/buttonA"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Button-A"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constraintTop_toTopOf="parent" />

<Button
    android:id="@+id/buttonB"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Button-B"
    android:layout_marginRight="20dp"
    app:layout_constraintRight_toLeftOf="@+id/buttonA"
    app:layout_constraintTop_toTopOf="@id/buttonA" />

<Button
    android:id="@+id/buttonC"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Button-C"
    android:layout_marginTop="20dp"
    app:layout_constraintTop_toBottomOf="@id/buttonA"
    app:layout_constraintLeft_toLeftOf="@id/buttonA"/>

<Button
    android:id="@+id/buttonD"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginLeft="20dp"
    android:text="Button-D"
    app:layout_constraintLeft_toRightOf="@id/buttonA"
    app:layout_constraintTop_toTopOf="@+id/buttonA"
    />

<Button
    android:id="@+id/buttonE"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Button-E"
    android:layout_marginBottom="20dp"
    app:layout_constraintBottom_toTopOf="@id/buttonA"
    app:layout_constraintLeft_toLeftOf="@id/buttonA"
    />


<!--在buttonGone1的屬性設(shè)置為android:visibility="gone" ,buttonGone2的外邊距l(xiāng)ayout_goneMarginLeft生效-->
<Button
    android:id="@+id/buttonGone1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:visibility="gone"
    android:text="buttonGone-1"
    />

<Button
    android:id="@+id/buttonGone2"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:layout_goneMarginLeft="80dp"
    app:layout_constraintLeft_toRightOf="@id/buttonGone1"
    android:text="buttonGone-2"
    />

</android.support.constraint.ConstraintLayout>

(二)基本特性

1妆艘,偏移(Bias)
在上文第二張圖全屏居中的例子中彤灶,你可能發(fā)現(xiàn)了布局中有藍(lán)色的彈簧線,他是不是很像拉力呢批旺,像是四條彈簧將按鈕平衡的拉到中心的呢枢希,事實(shí)上也是這樣的。你對(duì)父布局的邊做為相對(duì)目標(biāo)朱沃,而button卻很小,無(wú)法被拉伸到每個(gè)邊界茅诱,所以button被拉到了居中的位置逗物,在ConstraintLayout中也用這種方式進(jìn)行全屏居中,水平或垂直居中瑟俭,這種作用在布局的拉力翎卓,我們是可以控制拉力的大小的,也就是我們的主角偏移摆寄,先來(lái)看兩個(gè)屬性失暴。

layout_constraintHorizontal_bias
layout_constraintVertical_bias

很容易的看出是水平偏移和垂直偏移,那就試試吧微饥。


29758665-856D-444E-84C7-03759B280254.png
<Button
    android:id="@+id/buttonA"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Button-A"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constraintHorizontal_bias="0.3"
    app:layout_constraintVertical_bias="0.8"
    app:layout_constraintTop_toTopOf="parent" />

橫向偏移了0.3逗扒,縱向偏移了0.8,相當(dāng)于按百分比偏移了控件欠橘,這種力只有設(shè)置parent才會(huì)出現(xiàn)嗎矩肩?當(dāng)然不是,可以約束到任何邊上肃续,再看一個(gè)例子:


962BB2B3-8496-48E6-A19D-564B0E265223.png

從圖中可以看到黍檩,底部按鈕的左邊約束到父布局,右側(cè)約束給了偏移例子的按鈕右側(cè)始锚,這樣就會(huì)出現(xiàn)這種平衡力刽酱,那么按鈕應(yīng)該在中間來(lái)平衡這個(gè)關(guān)系才對(duì)。當(dāng)然了瞧捌,是我做了手腳棵里,加了偏移,橫向偏移0.8 看下代碼:

<Button
    android:id="@+id/button1"
    android:layout_width="201dp"
    android:layout_height="wrap_content"
    android:text="偏移例子"
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constraintLeft_toLeftOf="parent"
    />

<Button
    android:id="@+id/button2"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="底部按鈕"
    android:layout_marginTop="112dp"
    app:layout_constraintRight_toRightOf="@+id/button1"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintTop_toTopOf="@+id/button1"
    app:layout_constraintHorizontal_bias="0.8" />

也就是說你在一個(gè)范圍內(nèi)想擺放這個(gè)按鈕,就可以根據(jù)你的相對(duì)控件衍慎,寫出這種平衡力转唉,配合偏移來(lái)調(diào)整位置。

如果你想讓一個(gè)控件的中心上下對(duì)齊一個(gè)控件的一條邊呢稳捆,你可以約束這個(gè)組件的左側(cè)邊和右側(cè)邊同時(shí)約束你要居中的邊赠法,看一下例子:

A830A12B-0F61-4524-B8F7-D19CBB5DD266.png

圖的上方是一個(gè)常規(guī)的以控件中心居中,跟以父布局沒區(qū)別乔夯,下面是我們要的砖织,以一條邊居中,看一下代碼:

<Button
    android:id="@+id/button1"
    android:layout_width="201dp"
    android:layout_height="wrap_content"
    android:text="偏移例子"
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constraintLeft_toLeftOf="parent"
    />

<Button
    android:id="@+id/button2"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="底部按鈕"
    android:layout_marginTop="112dp"
    app:layout_constraintRight_toRightOf="@+id/button1"
    app:layout_constraintLeft_toLeftOf="@+id/button1"
    app:layout_constraintTop_toTopOf="@+id/button1"
     />

<Button
    android:id="@+id/button3"
    android:layout_width="201dp"
    android:layout_height="wrap_content"
    android:text="偏移例子"
    app:layout_constraintTop_toTopOf="parent"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constraintLeft_toLeftOf="parent"
    />

<Button
    android:id="@+id/button4"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="底部按鈕"
    android:layout_marginTop="112dp"
    app:layout_constraintRight_toRightOf="@+id/button3"
    app:layout_constraintLeft_toRightOf="@+id/button3"
    app:layout_constraintTop_toTopOf="@+id/button3"
    />

2末荐,圓心定位(Circular positioning)

circle1.png
circle2.png

看一個(gè)三個(gè)屬性
layout_constraintCircle : references another widget id
layout_constraintCircleRadius : the distance to the other widget center
layout_constraintCircleAngle : which angle the widget should be at (in degrees, from 0 to 360)

<Button android:id="@+id/buttonA" ... />
  <Button android:id="@+id/buttonB" ...
  app:layout_constraintCircle="@+id/buttonA"
  app:layout_constraintCircleRadius="100dp"
  app:layout_constraintCircleAngle="45" />

我還沒想到有哪些場(chǎng)景能用到侧纯。暫時(shí)上一個(gè)官方的例子在這里吧。表示我來(lái)過甲脏。

3眶熬,可見性行為(Visibility behavior)
翻譯一下文檔。

ConstraintLayout對(duì)控件的特定處理標(biāo)記為View.GONE块请。

像其他的布局一樣娜氏,設(shè)置為GONE的控件不會(huì)顯示,也不是布局本身的一部分(即如果標(biāo)記為GONE墩新,它們的實(shí)際尺寸將不會(huì)更改)

但就布局計(jì)算而言贸弥,GONE控件仍然是其中的一部分,具有重要的區(qū)別:

1海渊,對(duì)于布局傳遞绵疲,它們的尺寸將被視為零(基本上,它們將被解析為一個(gè)點(diǎn))
2臣疑,如果他們對(duì)其他控件有約束盔憨,他們?nèi)匀粫?huì)生效,但任何邊距都會(huì)等于零

visibility-behavior (2).png

您可以暫時(shí)將窗口控件標(biāo)記為GONE讯沈,而不會(huì)破壞布局般渡,這在進(jìn)行簡(jiǎn)單的布局動(dòng)畫時(shí)尤其有用。

注意:使用的邊距將是B在連接到A時(shí)定義的邊距芙盘。在某些情況下驯用,這可能不是您想要的剩余邊距(例如A在其容器側(cè)面有100dp的邊距,B只有16dp到A儒老,A標(biāo)記為已消失蝴乔,B對(duì)容器的邊距為16dp)。因此驮樊,您可以指定在連接到標(biāo)記為已消失的窗口小部件時(shí)要使用的備用邊距值(請(qǐng)參閱上面有關(guān)已刪除邊距屬性的部分)薇正。

4片酝,尺寸約束(Dimensions constraints)

首先區(qū)分一下在ConstraintLayout 中android:layout_width和android:layout_height有什么區(qū)別

image.png
<Button
    android:id="@+id/btn1"
    android:layout_width="200dp"
    android:layout_height="wrap_content"
    android:text="200dp"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent" />

<Button
    android:id="@+id/btn2"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="wrap_content"
    app:layout_constraintTop_toBottomOf="@+id/btn1"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent" />


<Button
    android:id="@+id/btn3"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:text="0dp"
    app:layout_constraintTop_toBottomOf="@id/btn2"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent" />

可以看到主要的區(qū)別就是match_parent對(duì)應(yīng)ConstraintLayout的0dp了。官方不推薦在ConstraintLayout中使用match_parent挖腰,添加相對(duì)父布局位置的約束配合0dp的width和height也能實(shí)現(xiàn)效果雕沿。


image.png

第一種則是設(shè)置固定大小,第二種則是0dp猴仑,第三種是0dp加上margin审轮。

繼續(xù)看一下 約束尺寸的四個(gè)屬性:
android:minWidth
android:minHeight
android:maxWidth
android:maxHeight

很明顯是設(shè)置寬高的最大值和最小值,當(dāng)其尺寸設(shè)置為WRAP_CONTENT時(shí)辽俗,ConstraintLayout將使用這些最小和最大尺寸疾渣。

 <Button
    android:id="@+id/btn1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="有一個(gè)很長(zhǎng)的故事~~~~~~~~~~~~"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent"
    android:maxWidth="40dp"
    android:minWidth="3dp" />

可以看到文字應(yīng)該是超過了40dp所能容納的大小,我設(shè)置了最大只能40dp崖飘。效果圖:

image.png

5榴捡,WRAP_CONTENT : 強(qiáng)制約束( enforcing constraints )

官方譯文:
如果寬高設(shè)置為WRAP_CONTENT,則在1.1之前的版本中朱浴,它們將被視為文字寬高 - 這意味著約束不會(huì)限制生成的寬高吊圾。雖然通常這足夠(并且更快),但在某些情況下翰蠢,您可能希望使用WRAP_CONTENT街夭,但仍然強(qiáng)制執(zhí)行約束以限制生成的寬高。在這種情況下躏筏,您可以添加一個(gè)相應(yīng)的屬性:

app:layout_constrainedWidth=”true|false”
app:layout_constrainedHeight=”true|false”

如果設(shè)置為WRAP_CONTENT,就是如果文字的寬高改變了呈枉,約束就失效了趁尼,比如你的text里面文字太多,直接就把約束搞沒了猖辫,為什么會(huì)有這樣的機(jī)制呢酥泞,因?yàn)橛械臅r(shí)候我們的需求更關(guān)心于顯示的文字,看需求而定要不要這個(gè)屬性啃憎,這是我的理解芝囤。

說個(gè)例子。

image.png
<Button
    android:id="@+id/btn1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="有一個(gè)的故事"
    />
<Button
    android:id="@+id/btn2"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:layout_constraintLeft_toRightOf="@id/btn1"
    app:layout_constraintRight_toRightOf="parent"
    android:text="有一個(gè)小和尚"
    />

很常規(guī)的一個(gè)相對(duì)關(guān)系辛萍,右側(cè)按鈕左邊相對(duì)左側(cè)按鈕的右邊悯姊,右側(cè)按鈕右邊相對(duì)夫布局,如果按剛才的說法贩毕,文字增長(zhǎng)悯许,會(huì)使布局約束失效。


image.png
<Button
    android:id="@+id/btn1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="有一個(gè)的故事"
    />
<Button
    android:id="@+id/btn2"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:layout_constraintLeft_toRightOf="@id/btn1"
    app:layout_constraintRight_toRightOf="parent"
    android:text="有一個(gè)小和尚,有一個(gè)小和尚有一個(gè)小和尚有一個(gè)小和尚有一個(gè)小和尚有一個(gè)小和尚有一個(gè)小和尚"
    />

可以看到右側(cè)按鈕的文本增多辉阶,導(dǎo)致約束失效先壕,然后我們?cè)囋噺?qiáng)制約束的屬性app:layout_constrainedHeight=”true瘩扼。

image.png
 <Button
    android:id="@+id/btn1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="有一個(gè)的故事"
    />
<Button
    android:id="@+id/btn2"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:layout_constraintLeft_toRightOf="@id/btn1"
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constrainedWidth="true"
    android:text="有一個(gè)小和尚,有一個(gè)小和尚有一個(gè)小和尚有一個(gè)小和尚有一個(gè)小和尚有一個(gè)小和尚有一個(gè)小和尚"
    />

我們就可以根據(jù)這個(gè)屬性來(lái)約束強(qiáng)制保證我們的布局。

6垃僚,MATCH_CONSTRAINT (0dp)

看幾個(gè)屬性:

layout_constraintWidth_min and layout_constraintHeight_min :
layout_constraintWidth_max and layout_constraintHeight_max :
layout_constraintWidth_percent and layout_constraintHeight_percent :

上面兩個(gè)和WRAP_CONTENT的最大最小值寬高類似集绰,寫一個(gè)一樣的例子試試。

image.png
   <Button
    android:id="@+id/btn1"
    android:layout_width="0dp"
    android:layout_height="0dp"
    android:text="有一個(gè)很長(zhǎng)的故事~~~~~~~~~~~~"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constraintTop_toTopOf="parent"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintWidth_max="40dp"
    app:layout_constraintWidth_min="3dp" />

如果不寫相對(duì)關(guān)系的話是出不來(lái)的谆棺,因?yàn)樗?dp栽燕。是的,他需要相對(duì)關(guān)系的支撐包券。像這個(gè)寬高都為0的纫谅,四個(gè)方向都要寫相對(duì)關(guān)系的〗蹋總之存在于這個(gè)布局中就要存在相對(duì)關(guān)系的付秕。

需要注意的是不僅僅可以設(shè)置多少dp,還可以設(shè)置app:layout_constraintWidth_min="wrap"侍郭,這歌wrap代表的是wrap_content询吴。

還剩下最后一個(gè)屬性layout_constraintWidth_percent and layout_constraintHeight_percent :

設(shè)置這個(gè)屬性需要幾個(gè)前提:

1, 寬高應(yīng)設(shè)置為MATCH_CONSTRAINT(0dp)
2亮元,默認(rèn)值應(yīng)設(shè)置為app app:layout_constraintWidth_default =“percent”或app:layout_constraintHeight_default =“percent”
(注意:這在1.1-beta1和1.1-beta2中是必需的猛计,但是如果定義了percent屬性,則在以下版本中不需要)
3爆捞,然后將layout_constraintWidth_percent或layout_constraintHeight_percent屬性設(shè)置為0到1之間的值來(lái)定義百分值奉瘤。

總結(jié)一句話,通俗的講就是設(shè)置自己的尺寸是父容器的多少百分值煮甥,需要按上述步驟來(lái)寫盗温。

來(lái)看一下例子:

image.png
<Button
    android:id="@+id/btn1"
    android:layout_width="0dp"
    app:layout_constraintWidth_default="percent"
    app:layout_constraintWidth_percent="0.8"
    android:layout_height="wrap_content"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent"
    android:text="有一個(gè)的故事"
    />

占用了父控件的80%,沒什么好說的成肘。

7卖局,比率 (Ratio)

先看一下屬性:
app:layout_constraintDimensionRatio

這個(gè)比率的意思是當(dāng)前自身控件的橫縱比,也就是寬和高的比可以通過一個(gè)比值來(lái)控制双霍。前提是至少需要寬或者高為0dp砚偶,以這種形式設(shè)置width:height;

還有一種形式洒闸,先看一下文檔是如何描述的染坯。

如果兩個(gè)尺寸都設(shè)置為MATCH_CONSTRAINT(0dp),也可以使用比率丘逸。在這種情況下酒请,系統(tǒng)設(shè)置滿足所有約束的最大尺寸并保持指定的縱橫比。要根據(jù)另一個(gè)特定邊的尺寸約束一個(gè)特定邊鸣个,可以預(yù)先附加W或H羞反,分別約束寬度或高度布朦。例如,如果一個(gè)寬高受兩個(gè)目標(biāo)約束(例如昼窗,寬度為0dp并且以父對(duì)象為中心)你可以通過在比率前添加字母W(用于約束寬度)或H(用于約束高度)來(lái)指示哪一邊應(yīng)該被約束是趴,用逗號(hào)分隔:

也就是說寬鋪面屏幕,按16來(lái)算澄惊,高度根據(jù)16的9份來(lái)展示唆途。

看一下例子:

image.png
<Button
    android:id="@+id/btn1"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    app:layout_constraintDimensionRatio="1:1"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constraintBottom_toBottomOf="parent"
    android:text="有一個(gè)的故事"
    />

<Button
    android:id="@+id/btn2"
    android:layout_width="0dp"
    android:layout_height="0dp"
    app:layout_constraintDimensionRatio="h,16:9"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent"
    android:text="banner"
    />

7,鏈 (Chains)

image.png

鏈在單個(gè)軸(水平或垂直)上提供類似行的行為掸驱。另一個(gè)軸可以獨(dú)立約束

鏈由鏈的第一個(gè)元素(鏈的“頭部”)上設(shè)置的屬性控制:

image.png

首先肛搬,我們之前講到的都是單向的相對(duì)關(guān)系,如果互相建立相對(duì)關(guān)系毕贼,就是鏈温赔,鏈分水平鏈和垂直鏈,無(wú)論是水平和垂直第一個(gè)控件就叫做鏈頭鬼癣,水平就是最左是鏈頭陶贼,垂直就是最上是鏈頭。如果給鏈的設(shè)置magin待秃,則整個(gè)鏈都會(huì)響應(yīng)這個(gè)邊距拜秧,然后用剩余空間去調(diào)整這個(gè)鏈。

看你一下例子:

image.png
<Button
    android:id="@+id/btn1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toLeftOf="@id/btn2"
    android:layout_marginLeft="50dp"
    android:text="1"/>

<Button
    android:id="@+id/btn2"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:layout_constraintLeft_toRightOf="@+id/btn1"
    app:layout_constraintRight_toLeftOf="@+id/btn3"
    android:text="1"/>
<Button
    android:id="@+id/btn3"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:layout_constraintLeft_toRightOf="@+id/btn2"
    app:layout_constraintRight_toRightOf="parent"
    android:text="1"/>

鏈的幾種風(fēng)格 Chain Style

image.png

在鏈的第一個(gè)元素上設(shè)置屬性layout_constraintHorizo??ntal_chainStyle或layout_constraintVertical_chainStyle時(shí)章郁,鏈的行為將根據(jù)指定的樣式更改(默認(rèn)為CHAIN_SPREAD)

看幾個(gè)屬性值:

CHAIN_SPREAD - 元素將展開(默認(rèn)樣式)
Weighted chain - 在CHAIN_SPREAD模式下枉氮,如果控件設(shè)置為MATCH_CONSTRAINT(0dp),它們將拆分可用空間
CHAIN_SPREAD_INSIDE - 與默認(rèn)類似暖庄,但是鏈的端點(diǎn)將不會(huì)展開
CHAIN_PACKED - 鏈的元素將被打包在一起聊替。然后,子項(xiàng)的水平或垂直偏差屬性將影響打包元素的定位

通俗的講就三種模式

1,spread

2,spread_inside

3, packed

其他的都是一種擴(kuò)展用法雄驹。

手寫一下上面的例子更好的理解:

image.png
 <Button
    android:id="@+id/btn1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toLeftOf="@id/btn2"
    app:layout_constraintHorizontal_chainStyle="spread"
    android:text="spread"/>

<Button
    android:id="@+id/btn2"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:layout_constraintLeft_toRightOf="@+id/btn1"
    app:layout_constraintRight_toLeftOf="@+id/btn3"
    android:text="spread"/>
<Button
    android:id="@+id/btn3"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:layout_constraintLeft_toRightOf="@+id/btn2"
    app:layout_constraintRight_toRightOf="parent"
    android:text="spread"/>


<Button
    android:id="@+id/btn4"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="spread_inside"
    app:layout_constraintHorizontal_chainStyle="spread_inside"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toLeftOf="@+id/btn5"
    app:layout_constraintTop_toBottomOf="@+id/btn1" />

<Button
    android:id="@+id/btn5"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:layout_constraintLeft_toRightOf="@+id/btn4"
    app:layout_constraintRight_toLeftOf="@+id/btn6"
    app:layout_constraintTop_toBottomOf="@+id/btn2"
    android:text="spread_inside"/>
<Button
    android:id="@+id/btn6"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:layout_constraintTop_toBottomOf="@+id/btn3"
    app:layout_constraintLeft_toRightOf="@+id/btn5"
    app:layout_constraintRight_toRightOf="parent"
    android:text="spread_inside"/>

<Button
    android:id="@+id/btn7"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:text="weight-1份"
    app:layout_constraintHorizontal_chainStyle="spread"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toLeftOf="@+id/btn8"
    app:layout_constraintHorizontal_weight="1"
    app:layout_constraintTop_toBottomOf="@+id/btn4" />

<Button
    android:id="@+id/btn8"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    app:layout_constraintLeft_toRightOf="@+id/btn7"
    app:layout_constraintHorizontal_weight="2"
    app:layout_constraintRight_toLeftOf="@+id/btn9"
    app:layout_constraintTop_toBottomOf="@+id/btn5"
    android:text="weight-2份"/>
<Button
    android:id="@+id/btn9"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:text="weight-1份"
    app:layout_constraintTop_toBottomOf="@+id/btn6"
    app:layout_constraintHorizontal_weight="1"
    app:layout_constraintLeft_toRightOf="@+id/btn8"
    app:layout_constraintRight_toRightOf="parent"
    />

<Button
    android:id="@+id/btn11"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="packed"
    app:layout_constraintHorizontal_chainStyle="packed"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toLeftOf="@+id/btn22"
    app:layout_constraintTop_toBottomOf="@+id/btn7" />

<Button
    android:id="@+id/btn22"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:layout_constraintLeft_toRightOf="@+id/btn11"
    app:layout_constraintRight_toLeftOf="@+id/btn33"
    app:layout_constraintTop_toBottomOf="@+id/btn8"
    android:text="packed"/>
<Button
    android:id="@+id/btn33"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:layout_constraintTop_toBottomOf="@+id/btn9"
    app:layout_constraintLeft_toRightOf="@+id/btn22"
    app:layout_constraintRight_toRightOf="parent"
    android:text="packed"/>

<Button
    android:id="@+id/btn44"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="packed-bias0.3"
    app:layout_constraintHorizontal_chainStyle="packed"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toLeftOf="@+id/btn55"
    app:layout_constraintTop_toBottomOf="@+id/btn11"
    app:layout_constraintHorizontal_bias="0.3"/>

<Button
    android:id="@+id/btn55"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:layout_constraintLeft_toRightOf="@+id/btn44"
    app:layout_constraintRight_toLeftOf="@+id/btn66"
    app:layout_constraintTop_toBottomOf="@+id/btn22"
    android:text="packed-bias0.3"/>
<Button
    android:id="@+id/btn66"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:layout_constraintTop_toBottomOf="@+id/btn33"
    app:layout_constraintLeft_toRightOf="@+id/btn55"
    app:layout_constraintRight_toRightOf="parent"
    android:text="packed-bias0.3"/>

然后我們就能在橫向縱向的鏈中使用這個(gè)模式了,注意的是僅僅在鏈頭設(shè)置就好了淹辞。

在看一段官方譯文:

在水平鏈上医舆,如果一個(gè)元素定義了10dp的右邊距而下一個(gè)元素定義了5dp的左邊距,則這兩個(gè)元素之間產(chǎn)生的邊距為15dp象缀。

在計(jì)算鏈用于定位項(xiàng)目的剩余空間時(shí)蔬将,會(huì)同時(shí)考慮項(xiàng)目及其邊距。剩余空間不包含邊距央星。

8霞怀,約束線 (Guideline)

暫且就叫約束線吧,約束線就是一個(gè)虛線莉给,讓我們可以隨意的去定義一條線來(lái)輔助布局毙石,當(dāng)然它在布局顯示的時(shí)候是不可見的,可以水平可以垂直廉沮,通android:orientation=""來(lái)設(shè)置,值為vertical&horizontal徐矩。

看一下屬性:
app:layout_constraintGuide_percent:

app:layout_constraintGuide_start:

app:layout_constraintGuide_end:

image.png
 <android.support.constraint.Guideline
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/guideline"
    app:layout_constraintGuide_percent="0.3"
    android:orientation="vertical"/>

<Button
    android:text="Button"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/button"
    app:layout_constraintLeft_toLeftOf="@+id/guideline"
    android:layout_marginTop="16dp"
    app:layout_constraintTop_toTopOf="parent" />

我設(shè)置了一個(gè)百分比的屬性做為例子滞时,start和end類似,設(shè)置具體的大小滤灯,start就是從左側(cè)開始坪稽,end就是從右側(cè)開始。

再看一個(gè)稍微線多一點(diǎn)的官方例子鳞骤,


image.png
<android.support.constraint.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:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">

<Button
    android:id="@+id/button4"
    android:layout_width="wrap_content"
    android:layout_height="0dp"
    android:text="@string/button"
    android:layout_marginStart="8dp"
    app:layout_constraintLeft_toLeftOf="@+id/guideline"
    android:layout_marginLeft="8dp"
    app:layout_constraintBaseline_toBaselineOf="@+id/button5"
    app:layout_constraintRight_toLeftOf="@+id/guideline3"
    android:layout_marginRight="8dp"
    app:layout_constraintHorizontal_bias="0.9" />

<Button
    android:id="@+id/button5"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/button"
    app:layout_constraintRight_toLeftOf="@+id/guideline2"
    android:layout_marginRight="8dp"
    android:layout_marginEnd="8dp"
    app:layout_constraintLeft_toLeftOf="@+id/guideline3"
    android:layout_marginLeft="8dp"
    app:layout_constraintHorizontal_bias="0.5"
    app:layout_constraintTop_toTopOf="@+id/guideline4"
    android:layout_marginTop="16dp" />

<Button
    android:id="@+id/button6"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/button"
    app:layout_constraintRight_toLeftOf="@+id/guideline2"
    tools:layout_constraintTop_creator="1"
    tools:layout_constraintRight_creator="1"
    android:layout_marginEnd="5dp"
    android:layout_marginTop="4dp"
    app:layout_constraintTop_toTopOf="@+id/guideline5"
    android:layout_marginRight="8dp"
    android:layout_marginLeft="8dp"
    app:layout_constraintLeft_toLeftOf="@+id/guideline3"
    app:layout_constraintHorizontal_bias="0.5" />

<TextView
    android:id="@+id/textView3"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:text="@string/guidelines"
    android:textSize="30sp"
    tools:layout_constraintTop_creator="1"
    tools:layout_constraintRight_creator="1"
    app:layout_constraintRight_toRightOf="parent"
    android:layout_marginTop="16dp"
    tools:layout_constraintLeft_creator="1"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintTop_toTopOf="parent"
    android:layout_marginLeft="16dp"
    app:layout_constraintHorizontal_bias="0.0"
    android:layout_marginRight="16dp" />

<Button
    android:id="@+id/button7"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/button"
    tools:layout_constraintTop_creator="1"
    android:layout_marginStart="8dp"
    app:layout_constraintTop_toBottomOf="@+id/button6"
    tools:layout_constraintLeft_creator="1"
    app:layout_constraintLeft_toLeftOf="@+id/guideline"
    android:layout_marginTop="0dp" />

<Button
    android:id="@+id/button8"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/button"
    tools:layout_constraintTop_creator="1"
    android:layout_marginStart="10dp"
    android:layout_marginTop="8dp"
    tools:layout_constraintLeft_creator="1"
    app:layout_constraintLeft_toLeftOf="@+id/guideline"
    app:layout_constraintTop_toTopOf="@+id/guideline6" />

<android.support.constraint.Guideline
    android:layout_width="0dp"
    android:layout_height="0dp"
    android:id="@+id/guideline"
    android:orientation="vertical"
    app:layout_constraintGuide_percent="0.15" />

<android.support.constraint.Guideline
    android:layout_width="0dp"
    android:layout_height="0dp"
    android:id="@+id/guideline2"
    android:orientation="vertical"
    app:layout_constraintGuide_percent="0.85" />

<android.support.constraint.Guideline
    android:layout_width="0dp"
    android:layout_height="0dp"
    android:id="@+id/guideline3"
    android:orientation="vertical"
    app:layout_constraintGuide_percent="0.5" />

<android.support.constraint.Guideline
    android:layout_width="0dp"
    android:layout_height="0dp"
    android:id="@+id/guideline4"
    android:orientation="horizontal"
    app:layout_constraintGuide_percent="0.15" />

<android.support.constraint.Guideline
    android:layout_width="0dp"
    android:layout_height="0dp"
    android:id="@+id/guideline5"
    android:orientation="horizontal"
    app:layout_constraintGuide_percent="0.50097847" />

<android.support.constraint.Guideline
    android:layout_width="0dp"
    android:layout_height="0dp"
    android:id="@+id/guideline6"
    android:orientation="horizontal"
    app:layout_constraintGuide_percent="0.85" />

</android.support.constraint.ConstraintLayout>

這個(gè)屬性tools:layout_constraintTop_creator="1"窒百,可以忽略。

9豫尽,屏障 (Barrier)
這個(gè)不是LOL里的屏障篙梢,只是直譯過來(lái)的大家要區(qū)分開,Barrier類似 Guideline都是虛擬存在的輔助開發(fā)的視圖拂募。把多個(gè)控件看為整體確定一條約束線庭猩。Barrier之外的控件跟隨Barrier的內(nèi)容改變而自適應(yīng)。

先看一下屬性:

app:barrierDirection="start" 確定Barrier方向可選值有l(wèi)eft, right, top, bottom, start, end
app:constraint_referenced_ids="button1,button2" 確定Barrier的控件集合陈症。

 <android.support.constraint.Barrier
          android:id="@+id/barrier"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          app:barrierDirection="start"
          app:constraint_referenced_ids="button1,button2" />
image.png

上圖方向?yàn)镾tart蔼水,在組件集合1,2的開始的地方豎起了屏障录肯,如果是end呢趴腋?


image.png

在最寬的控件上豎起了屏障燎竖,在很多類似的場(chǎng)景下需要嵌套布局巷怜,這就是Barrier存在的含義吧。

如果控件尺寸發(fā)生變化境蔼,屏障將根據(jù)其方向自動(dòng)移動(dòng)以獲得極限的控件


image.png

這種情況我并沒有試出來(lái)厅贪。

10蠢护,動(dòng)畫 (ConstraintSet)
讓布局平滑的切換。直接上一個(gè)官方的例子吧:

Screenshot_1532008110.png

Screenshot_1532008113.png

上面兩張圖片平滑的動(dòng)畫切換养涮,

constraintset_example_big.xml

<android.support.constraint.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:id="@+id/activity_constraintset_example"
android:layout_width="match_parent"
android:layout_height="match_parent" >

<ImageView
    android:id="@+id/imageView"
    android:layout_width="0dp"
    android:layout_height="0dp"
    android:layout_marginEnd="24dp"
    android:layout_marginStart="24dp"
    android:layout_marginTop="24dp"
    android:onClick="toggleMode"
    android:scaleType="centerCrop"
    android:src="@drawable/lake"
    app:layout_constraintDimensionRatio="h,16:9"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constraintTop_toTopOf="parent"
    tools:layout_constraintLeft_creator="1"
    tools:layout_constraintRight_creator="1"
    android:contentDescription="@string/lake_tahoe_image" />

<TextView
    android:id="@+id/textView9"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/lake_tahoe_title"
    android:textSize="30sp"
    app:layout_constraintLeft_toLeftOf="@+id/imageView"
    android:layout_marginTop="8dp"
    app:layout_constraintTop_toBottomOf="@+id/imageView" />

<TextView
    android:id="@+id/textView11"
    android:layout_width="0dp"
    android:layout_height="0dp"
    android:text="@string/lake_discription"
    app:layout_constraintLeft_toLeftOf="@+id/textView9"
    android:layout_marginTop="8dp"
    app:layout_constraintTop_toBottomOf="@+id/textView9"
    app:layout_constraintRight_toRightOf="@+id/imageView"
    app:layout_constraintBottom_toBottomOf="parent"
    android:layout_marginBottom="16dp"
    tools:layout_constraintTop_creator="1"
    tools:layout_constraintBottom_creator="1"
    app:layout_constraintHorizontal_bias="0.0"
    app:layout_constraintVertical_bias="0.0" />

</android.support.constraint.ConstraintLayout>

constraintset_example_main.xml

<android.support.constraint.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:id="@+id/activity_constraintset_example"
android:layout_width="match_parent"
android:layout_height="match_parent" >

<ImageView
    android:id="@+id/imageView"
    android:layout_width="0dp"
    android:layout_height="0dp"
    android:layout_marginStart="8dp"
    android:onClick="toggleMode"
    android:scaleType="centerCrop"
    android:src="@drawable/lake"
    app:layout_constraintBottom_toBottomOf="@+id/textView9"
    app:layout_constraintDimensionRatio="w,16:9"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintTop_toTopOf="@+id/textView9"
    tools:layout_constraintBottom_creator="1"
    tools:layout_constraintTop_creator="1"
    android:contentDescription="@string/lake_tahoe_image"
    app:layout_constraintVertical_bias="0.0" />

<TextView
    android:id="@+id/textView9"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginStart="8dp"
    android:layout_marginTop="16dp"
    android:text="@string/lake_tahoe_title"
    android:textSize="30sp"
    app:layout_constraintLeft_toRightOf="@+id/imageView"
    app:layout_constraintTop_toTopOf="parent" />

<TextView
    android:id="@+id/textView11"
    android:layout_width="0dp"
    android:layout_height="0dp"
    android:layout_marginBottom="8dp"
    android:layout_marginEnd="8dp"
    android:layout_marginStart="8dp"
    android:layout_marginTop="24dp"
    android:text="@string/lake_discription"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constraintTop_toBottomOf="@+id/imageView"
    tools:layout_constraintBottom_creator="1"
    tools:layout_constraintLeft_creator="1"
    tools:layout_constraintRight_creator="1"
    tools:layout_constraintTop_creator="1" />

</android.support.constraint.ConstraintLayout>

java

public class ConstraintSetExampleActivity extends AppCompatActivity {

private static final String SHOW_BIG_IMAGE = "showBigImage";

/**
 * Whether to show an enlarged image
 */
private boolean mShowBigImage = false;
/**
 * The ConstraintLayout that any changes are applied to.
 */
private ConstraintLayout mRootLayout;
/**
 * The ConstraintSet to use for the normal initial state
 */
private ConstraintSet mConstraintSetNormal = new ConstraintSet();
/**
 * ConstraintSet to be applied on the normal ConstraintLayout to make the Image bigger.
 */
private ConstraintSet mConstraintSetBig = new ConstraintSet();

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.constraintset_example_main);

    mRootLayout = (ConstraintLayout) findViewById(R.id.activity_constraintset_example);
    // Note that this can also be achieved by calling
    // `mConstraintSetNormal.load(this, R.layout.constraintset_example_main);`
    // Since we already have an inflated ConstraintLayout in `mRootLayout`, clone() is
    // faster and considered the best practice.
    mConstraintSetNormal.clone(mRootLayout);
    // Load the constraints from the layout where ImageView is enlarged.
    mConstraintSetBig.load(this, R.layout.constraintset_example_big);

    if (savedInstanceState != null) {
        boolean previous = savedInstanceState.getBoolean(SHOW_BIG_IMAGE);
        if (previous != mShowBigImage) {
            mShowBigImage = previous;
            applyConfig();
        }
    }
}

@Override
public void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    outState.putBoolean(SHOW_BIG_IMAGE, mShowBigImage);
}

// Method called when the ImageView within R.layout.constraintset_example_main
// is clicked.
public void toggleMode(View v) {
    TransitionManager.beginDelayedTransition(mRootLayout);
    mShowBigImage = !mShowBigImage;
    applyConfig();
}

private void applyConfig() {
    if (mShowBigImage) {
        mConstraintSetBig.applyTo(mRootLayout);
    } else {
        mConstraintSetNormal.applyTo(mRootLayout);
    }
}
}

11葵硕,運(yùn)動(dòng)布局 (motionlayout)

ConstraintLayout子類,很炫酷贯吓,可以讓布局動(dòng)起來(lái)懈凹,有興趣的自行了解吧。

谷歌官方Demo(包括ConstraintLayout和MotionLayout)
https://github.com/googlesamples/android-ConstraintLayoutExamples

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末悄谐,一起剝皮案震驚了整個(gè)濱河市介评,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌爬舰,老刑警劉巖们陆,帶你破解...
    沈念sama閱讀 207,248評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件寒瓦,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡棒掠,警方通過查閱死者的電腦和手機(jī)孵构,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,681評(píng)論 2 381
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)烟很,“玉大人颈墅,你說我怎么就攤上這事∥砀ぃ” “怎么了恤筛?”我有些...
    開封第一講書人閱讀 153,443評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)芹橡。 經(jīng)常有香客問我毒坛,道長(zhǎng),這世上最難降的妖魔是什么林说? 我笑而不...
    開封第一講書人閱讀 55,475評(píng)論 1 279
  • 正文 為了忘掉前任煎殷,我火速辦了婚禮,結(jié)果婚禮上腿箩,老公的妹妹穿的比我還像新娘豪直。我一直安慰自己,他們只是感情好珠移,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,458評(píng)論 5 374
  • 文/花漫 我一把揭開白布弓乙。 她就那樣靜靜地躺著,像睡著了一般钧惧。 火紅的嫁衣襯著肌膚如雪暇韧。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,185評(píng)論 1 284
  • 那天浓瞪,我揣著相機(jī)與錄音懈玻,去河邊找鬼。 笑死乾颁,一個(gè)胖子當(dāng)著我的面吹牛涂乌,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播钮孵,決...
    沈念sama閱讀 38,451評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼骂倘,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼眼滤!你這毒婦竟也來(lái)了巴席?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,112評(píng)論 0 261
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤诅需,失蹤者是張志新(化名)和其女友劉穎漾唉,沒想到半個(gè)月后荧库,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,609評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡赵刑,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,083評(píng)論 2 325
  • 正文 我和宋清朗相戀三年分衫,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片般此。...
    茶點(diǎn)故事閱讀 38,163評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡蚪战,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出铐懊,到底是詐尸還是另有隱情邀桑,我是刑警寧澤,帶...
    沈念sama閱讀 33,803評(píng)論 4 323
  • 正文 年R本政府宣布科乎,位于F島的核電站壁畸,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏茅茂。R本人自食惡果不足惜捏萍,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,357評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望空闲。 院中可真熱鬧令杈,春花似錦、人聲如沸进副。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,357評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)影斑。三九已至给赞,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間矫户,已是汗流浹背片迅。 一陣腳步聲響...
    開封第一講書人閱讀 31,590評(píng)論 1 261
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留皆辽,地道東北人柑蛇。 一個(gè)月前我還...
    沈念sama閱讀 45,636評(píng)論 2 355
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像驱闷,于是被迫代替她去往敵國(guó)和親耻台。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,925評(píng)論 2 344

推薦閱讀更多精彩內(nèi)容