前言
ConstraintLayout 是一個(gè)使用“相對(duì)定位”靈活地確定微件的位置和大小的一個(gè)布局两蟀,在 2016 年 Google I/O 中面世,它的出現(xiàn)是為了解決開發(fā)中過于復(fù)雜的頁(yè)面層級(jí)嵌套過多的問題——層級(jí)過深會(huì)增加繪制界面需要的時(shí)間私杜,影響用戶體驗(yàn)黔龟,以靈活的方式定位和調(diào)整小部件。從 Android Studio 2.3起穷蛹,創(chuàng)建layout文件就已經(jīng)是默認(rèn)ConstraintLayout了秤朗,但是盡管Google如此大力推這項(xiàng)技術(shù)煤蹭,但在當(dāng)時(shí)很少有人使用,近些年逐漸被大家拿起來取视,啊真香O踉怼(此處無圖勝有圖)。目前ConstraintLayout正式版已經(jīng)更新至2.0.4作谭,本文將帶領(lǐng)大家熟悉ConstraintLayout全部?jī)?nèi)容稽物。
轉(zhuǎn)載于Quyunshuo作者
Quyunshuo的博客地址:
https://juejin.cn/user/78820569533070/posts
布局的使用
位置約束
ConstraintLayout采用方向約束的方式對(duì)控件進(jìn)行定位,至少要保證水平和垂直方向都至少有一個(gè)約束才能確定控件的位置
-
基本方向約束
<?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"
android:background="#DAF3FE"
tools:context=".MainActivity">
<TextView
android:layout_width="100dp"
android:layout_height="60dp"
android:background="@drawable/tv_bg"
android:gravity="center"
android:text="A"
android:textColor="@color/black"
android:textSize="25sp"
android:textStyle="bold"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="HardcodedText" />
</androidx.constraintlayout.widget.ConstraintLayout> </pre>
核心代碼是這兩行:
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
這兩行代碼的意思就是,控件的開始方向與父容器的開始方向?qū)R,控件的頂部方向與父容器的頂部方向?qū)R锐秦,其實(shí)layout_constraintStart_toStartOf也可以使用layout_constraintLeft_toLeftOf咪奖,但是使用start和end來表示左和右是為了考慮別的國(guó)家的習(xí)慣,有的國(guó)家開始方向是右酱床,所以使用start和end可以兼容這種情況羊赵。到這里就可以看到該控件使用layout_constraintStart_toStartOf和layout_constraintTop_toTopOf兩條約束確定了自己的位置,這里有一個(gè)使用技巧扇谣,就是昧捷,該控件的?罐寨?方向在哪個(gè)控件的靡挥??方向鸯绿,記住這一點(diǎn)就可以了跋破。那么下面就介紹下全部的約束屬性:
基本方向約束
我的什么位置在誰(shuí)的什么位置
app:layout_constraintTop_toTopOf="" 我的頂部和誰(shuí)的頂部對(duì)齊
app:layout_constraintBottom_toBottomOf="" 我的底部和誰(shuí)的底部對(duì)齊
app:layout_constraintLeft_toLeftOf="" 我的左邊和誰(shuí)的左邊對(duì)齊
app:layout_constraintRight_toRightOf="" 我的右邊和誰(shuí)的右邊對(duì)齊
app:layout_constraintStart_toStartOf="" 我的開始位置和誰(shuí)的開始位置對(duì)齊
app:layout_constraintEnd_toEndOf="" 我的結(jié)束位置和誰(shuí)的結(jié)束位置對(duì)齊
app:layout_constraintTop_toBottomOf="" 我的頂部位置在誰(shuí)的底部位置
app:layout_constraintStart_toEndOf="" 我的開始位置在誰(shuí)的結(jié)束為止
那么ConstraintLayout就是使用這些屬性來確定控件的位置,雖然比較多楞慈,但是有規(guī)律可循幔烛,沒有任何記憶壓力
- 基線對(duì)齊
我們有時(shí)候需要寫這樣的需求:兩個(gè)文本是基線對(duì)齊的,那就可以用到我們的一個(gè)屬性layout_constraintBaseline_toBaselineOf來實(shí)現(xiàn)囊蓝,它的意思就是這個(gè)控件的基線與誰(shuí)的基線對(duì)齊,代碼如下:
<?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"
android:background="#DAF3FE"
tools:context=".MainActivity"
tools:ignore="HardcodedText">
<TextView
android:id="@+id/tv1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="20"
android:textColor="@color/black"
android:textSize="50sp"
android:textStyle="bold"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/tv2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="¥"
android:textColor="@color/black"
android:textSize="20sp"
app:layout_constraintBaseline_toBaselineOf="@id/tv1"
app:layout_constraintStart_toEndOf="@id/tv1" />
</androidx.constraintlayout.widget.ConstraintLayout>
通過layout_constraintBaseline_toBaselineOf我們就可以讓兩個(gè)不同大小的文案基線對(duì)齊
-
角度約束
我們來實(shí)現(xiàn)一下下圖的UI狡恬,jetpack圖標(biāo)在android圖標(biāo)的45度方向,距離為60dp有些時(shí)候我們需要一個(gè)控件在某個(gè)控件的某個(gè)角度的位置令蛉,那么通過其他的布局其實(shí)是不太好實(shí)現(xiàn)的聚霜,但是ConstraintLayout為我們提供了角度位置相關(guān)的屬性
app:layout_constraintCircle="" 目標(biāo)控件id
app:layout_constraintCircleAngle="" 對(duì)于目標(biāo)的角度(0-360)
app:layout_constraintCircleRadius="" 到目標(biāo)中心的距離 </pre>
<?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"
android:background="#DAF3FE"
tools:context=".MainActivity"
tools:ignore="HardcodedText">
<ImageView
android:id="@+id/android"
android:layout_width="100dp"
android:layout_height="100dp"
android:src="@drawable/android"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="@+id/jetpack"
android:layout_width="60dp"
android:layout_height="60dp"
android:src="@drawable/jetpack"
app:layout_constraintCircle="@+id/android"
app:layout_constraintCircleAngle="45"
app:layout_constraintCircleRadius="70dp" />
</androidx.constraintlayout.widget.ConstraintLayout>
-
百分比偏移
有的時(shí)候我們需要讓控件在父布局的水平方向或垂直方向的百分之多少的位置蝎宇,可以使用如下屬性:
app:layout_constraintHorizontal_bias="" 水平偏移 取值范圍是0-1的小數(shù)
app:layout_constraintVertical_bias="" 垂直偏移 取值范圍是0-1的小數(shù) </pre>
示例:控件A在父布局水平方向偏移0.3(30%)弟劲,垂直方向偏移0.8(80%)
注意:在使用百分比偏移時(shí),需要指定對(duì)應(yīng)位置的約束條件
<?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"
android:background="#DAF3FE"
tools:context=".MainActivity"
tools:ignore="HardcodedText">
<TextView
android:layout_width="100dp"
android:layout_height="60dp"
android:background="@drawable/tv_bg"
android:gravity="center"
android:text="A"
android:textColor="@color/black"
android:textSize="25sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.3"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.8" />
</androidx.constraintlayout.widget.ConstraintLayout>
控件內(nèi)邊距姥芥、外邊距兔乞、GONE Margin
ConstraintLayout的內(nèi)邊距和外邊距的使用方式其實(shí)是和其他布局一致的
外邊距
android:layout_margin="0dp"
android:layout_marginStart="0dp"
android:layout_marginLeft="0dp"
android:layout_marginTop="0dp"
android:layout_marginEnd="0dp"
android:layout_marginRight="0dp"
android:layout_marginBottom="0dp"
內(nèi)邊距
android:padding="0dp"
android:paddingStart="0dp"
android:paddingLeft="0dp"
android:paddingTop="0dp"
android:paddingEnd="0dp"
android:paddingRight="0dp"
android:paddingBottom="0dp" </pre>
ConstraintLayout除此之外還有GONE Margin,當(dāng)依賴的目標(biāo)view隱藏時(shí)會(huì)生效的屬性凉唐,例如B被A依賴約束庸追,當(dāng)B隱藏時(shí)B會(huì)縮成一個(gè)點(diǎn),自身的margin效果失效台囱,A設(shè)置的GONE Margin就會(huì)生效淡溯,屬性如下:
示例:當(dāng)目標(biāo)控件是顯示的時(shí)候GONE Margin不會(huì)生效GONE Margin
app:layout_goneMarginBottom="0dp"
app:layout_goneMarginEnd="0dp"
app:layout_goneMarginLeft="0dp"
app:layout_goneMarginRight="0dp"
app:layout_goneMarginStart="0dp"
app:layout_goneMarginTop="0dp"
<?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"
android:background="#DAF3FE"
tools:context=".MainActivity"
tools:ignore="HardcodedText">
<TextView
android:id="@+id/A"
android:layout_width="100dp"
android:layout_height="60dp"
android:layout_marginStart="100dp"
android:layout_marginTop="100dp"
android:background="@drawable/tv_bg"
android:gravity="center"
android:text="A"
android:textColor="@color/black"
android:textSize="25sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<!-- 該控件設(shè)置了 layout_goneMarginStart="100dp" 當(dāng)A控件隱藏時(shí)才會(huì)生效 -->
<TextView
android:id="@+id/B"
android:layout_width="60dp"
android:layout_height="40dp"
android:background="@drawable/tv_bg"
android:gravity="center"
android:text="B"
android:textColor="@color/black"
android:textSize="25sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="@id/A"
app:layout_constraintStart_toEndOf="@id/A"
app:layout_constraintTop_toTopOf="@id/A"
app:layout_goneMarginStart="100dp" />
</androidx.constraintlayout.widget.ConstraintLayout>
當(dāng)目標(biāo)A控件隱藏時(shí),B的GONE Margin就會(huì)生效控件尺寸
-
尺寸限制
在ConstraintLayout中提供了一些尺寸限制的屬性簿训,可以用來限制最大咱娶、最小寬高度,這些屬性只有在給出的寬度或高度為wrap_content時(shí)才會(huì)生效强品,比如想給寬度設(shè)置最小或最大值膘侮,那寬度就必須設(shè)置為wrap_content,這個(gè)比較簡(jiǎn)單就不放示例代碼了的榛,具體的屬性如下:
android:minWidth="" 設(shè)置view的最小寬度
android:minHeight="" 設(shè)置view的最小高度
android:maxWidth="" 設(shè)置view的最大寬度
android:maxHeight="" 設(shè)置view的最大高度
-
0dp(MATCH_CONSTRAINT)
設(shè)置view的大小除了傳統(tǒng)的wrap_content琼了、指定尺寸、match_parent外困曙,ConstraintLayout還可以設(shè)置為0dp(MATCH_CONSTRAINT)表伦,并且0dp的作用會(huì)根據(jù)設(shè)置的類型而產(chǎn)生不同的作用,進(jìn)行設(shè)置類型的屬性是layout_constraintWidth_default和layout_constraintHeight_default慷丽,取值可為spread蹦哼、percent、wrap要糊。具體的屬性及示例如下:
app:layout_constraintWidth_default="spread|percent|wrap"
app:layout_constraintHeight_default="spread|percent|wrap" </pre>
spread(默認(rèn)):占用所有的符合約束的空間
<?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"
android:background="#DAF3FE"
tools:context=".MainActivity"
tools:ignore="HardcodedText">
<TextView
android:id="@+id/A"
android:layout_width="0dp"
android:layout_height="60dp"
android:layout_marginStart="50dp"
android:layout_marginTop="50dp"
android:layout_marginEnd="50dp"
android:background="@drawable/tv_bg"
android:gravity="center"
android:text="A"
android:textColor="@color/black"
android:textSize="25sp"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintWidth_default="spread" />
</androidx.constraintlayout.widget.ConstraintLayout>
可以看到纲熏,view的寬度適應(yīng)了所有有效的約束空間,左右留出了margin的設(shè)置值50dp锄俄,這種效果就就是:自身view的大小充滿可以配置的剩余空間局劲,因?yàn)樽笥壹s束的都是父布局,所以view可配置的空間是整個(gè)父布局的寬度奶赠,又因?yàn)樵O(shè)置了margin鱼填,所以會(huì)留出margin的大小,因?yàn)閟pread是默認(rèn)值毅戈,所以可以不寫 app:layout_constraintWidth_default="spread"苹丸。
percent:按照父布局的百分比設(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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#DAF3FE"
tools:context=".MainActivity"
tools:ignore="HardcodedText">
<TextView
android:id="@+id/A"
android:layout_width="0dp"
android:layout_height="60dp"
android:layout_marginTop="50dp"
android:background="@drawable/tv_bg"
android:gravity="center"
android:text="A"
android:textColor="@color/black"
android:textSize="25sp"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintWidth_default="percent"
app:layout_constraintWidth_percent="0.5" />
</androidx.constraintlayout.widget.ConstraintLayout>
percent模式的意思是自身view的尺寸是父布局尺寸的一定比例愤惰,上圖所展示的是寬度是父布局寬度的0.5(50%,取值是0-1的小數(shù))赘理,該模式需要配合layout_constraintWidth_percent使用宦言,但是寫了layout_constraintWidth_percent后,layout_constraintWidth_default="percent"其實(shí)就可以省略掉了商模。
wrap:匹配內(nèi)容大小但不超過約束限制
<?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"
android:background="#DAF3FE"
tools:context=".MainActivity"
tools:ignore="HardcodedText">
<!-- 寬度設(shè)置為wrap_content -->
<TextView
android:id="@+id/A"
android:layout_width="wrap_content"
android:layout_height="60dp"
android:layout_marginStart="100dp"
android:layout_marginTop="50dp"
android:layout_marginEnd="100dp"
android:background="@drawable/tv_bg"
android:gravity="center"
android:text="AAAAAAAAAAAAAAAAAA"
android:textColor="@color/black"
android:textSize="25sp"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintWidth_default="spread" />
<!-- 寬度設(shè)置為0dp wrap模式 -->
<TextView
android:id="@+id/B"
android:layout_width="0dp"
android:layout_height="60dp"
android:layout_marginStart="100dp"
android:layout_marginTop="150dp"
android:layout_marginEnd="100dp"
android:background="@drawable/tv_bg"
android:gravity="center"
android:text="BBBBBBBBBBBBBBBBBBBBBBB"
android:textColor="@color/black"
android:textSize="25sp"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintWidth_default="wrap" />
</androidx.constraintlayout.widget.ConstraintLayout>
這里寫了兩個(gè)控件作為對(duì)比奠旺,控件A寬度設(shè)置為wrap_content购裙,寬度適應(yīng)內(nèi)容大小旱爆,并且設(shè)置了margin,但是顯然寬度已經(jīng)超過margin的設(shè)置值了洞渔,而控件B寬度設(shè)置為0dp wrap模式嫂沉,寬度適應(yīng)內(nèi)容大小稽寒,并且不會(huì)超過margin的設(shè)置值,也就是不會(huì)超過約束限制趟章,這就是這兩者的區(qū)別杏糙。Google還提供了兩個(gè)屬性用于強(qiáng)制約束:
還是上一個(gè)例子,這里將控件A設(shè)置了強(qiáng)制約束蚓土,展示出的效果和控件B是一樣的了:當(dāng)一個(gè)view的寬或高,設(shè)置成wrap_content時(shí)
app:layout_constrainedWidth="true|false"
app:layout_constrainedHeight="true|false"
<?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"
android:background="#DAF3FE"
tools:context=".MainActivity"
tools:ignore="HardcodedText">
<TextView
android:id="@+id/A"
android:layout_width="wrap_content"
android:layout_height="60dp"
android:layout_marginStart="100dp"
android:layout_marginTop="50dp"
android:layout_marginEnd="100dp"
android:background="@drawable/tv_bg"
android:gravity="center"
android:text="AAAAAAAAAAAAAAAAAA"
android:textColor="@color/black"
android:textSize="25sp"
android:textStyle="bold"
app:layout_constrainedWidth="true"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintWidth_default="spread" />
</androidx.constraintlayout.widget.ConstraintLayout>
除此之外宏侍,0dp還有一些其他的獨(dú)特屬性用于設(shè)置尺寸的大小限制
app:layout_constraintWidth_min="" 0dp下,寬度的最小值
app:layout_constraintHeight_min="" 0dp下蜀漆,高度的最小值
app:layout_constraintWidth_max="" 0dp下谅河,寬度的最大值
app:layout_constraintHeight_max="" 0dp下,高度的最大值 </pre>
-
比例寬高(Ratio)
ConstraintLayout中可以對(duì)寬高設(shè)置比例确丢,前提是至少有一個(gè)約束維度設(shè)置為0dp绷耍,這樣比例才會(huì)生效,該屬性可使用兩種設(shè)置:
1. 浮點(diǎn)值鲜侥,表示寬度和高度之間的比率
2. 寬度:高度褂始,表示寬度和高度之間形式的比率
app:layout_constraintDimensionRatio="" 寬高比例
<?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"
android:background="#DAF3FE"
tools:context=".MainActivity"
tools:ignore="HardcodedText">
<TextView
android:id="@+id/A"
android:layout_width="0dp"
android:layout_height="100dp"
android:background="@drawable/tv_bg"
android:gravity="center"
android:text="A"
android:textColor="@color/black"
android:textSize="25sp"
android:textStyle="bold"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
Chains(鏈)
Chains(鏈)也是一個(gè)非常好用的特性,它是將許多個(gè)控件在水平或者垂直方向描函,形成一條鏈崎苗,用于平衡這些控件的位置,那么如何形成一條鏈呢舀寓?形成一條鏈要求鏈中的控件在水平或者垂直方向胆数,首尾互相約束,這樣就可以形成一條鏈互墓,水平方向互相約束形成的就是一條水平鏈必尼,反之則是垂直鏈,下面看示例:<?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"
android:background="#DAF3FE"
tools:context=".MainActivity"
tools:ignore="HardcodedText">
<TextView
android:id="@+id/A"
android:layout_width="80dp"
android:layout_height="80dp"
android:background="@drawable/tv_bg"
android:gravity="center"
android:text="A"
android:textColor="@color/black"
android:textSize="25sp"
android:textStyle="bold"
app:layout_constraintEnd_toStartOf="@id/B"
app:layout_constraintHorizontal_chainStyle="spread"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/B"
android:layout_width="80dp"
android:layout_height="80dp"
android:background="@drawable/tv_bg"
android:gravity="center"
android:text="B"
android:textColor="@color/black"
android:textSize="25sp"
android:textStyle="bold"
app:layout_constraintEnd_toStartOf="@id/C"
app:layout_constraintStart_toEndOf="@id/A"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/C"
android:layout_width="80dp"
android:layout_height="80dp"
android:background="@drawable/tv_bg"
android:gravity="center"
android:text="C"
android:textColor="@color/black"
android:textSize="25sp"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/B"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
A篡撵、B胰伍、C齿诞,三個(gè)控件在水平方向上首尾互相約束酸休,這樣就形成了一條水平鏈骂租,他們默認(rèn)的模式是spread,均分剩余空間斑司,我們可以使用layout_constraintHorizontal_chainStyle和layout_constraintVertical_chainStyle分別對(duì)水平和垂直鏈設(shè)置模式渗饮,模式可選的值有:spread、packed宿刮、spread_inside<?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"
android:background="#DAF3FE"
tools:context=".MainActivity"
tools:ignore="HardcodedText">
<TextView
android:id="@+id/A"
android:layout_width="0dp"
android:layout_height="80dp"
android:background="@drawable/tv_bg"
android:gravity="center"
android:text="A"
android:textColor="@color/black"
android:textSize="25sp"
android:textStyle="bold"
app:layout_constraintEnd_toStartOf="@id/B"
app:layout_constraintHorizontal_weight="2"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_chainStyle="packed" />
<TextView
android:id="@+id/B"
android:layout_width="0dp"
android:layout_height="80dp"
android:background="@drawable/tv_bg"
android:gravity="center"
android:text="B"
android:textColor="@color/black"
android:textSize="25sp"
android:textStyle="bold"
app:layout_constraintEnd_toStartOf="@id/C"
app:layout_constraintHorizontal_weight="1"
app:layout_constraintStart_toEndOf="@id/A"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/C"
android:layout_width="0dp"
android:layout_height="80dp"
android:background="@drawable/tv_bg"
android:gravity="center"
android:text="C"
android:textColor="@color/black"
android:textSize="25sp"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_weight="3"
app:layout_constraintStart_toEndOf="@id/B"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
輔助類
ConstraintLayout為了解決嵌套問題還提供了一系列的輔助控件幫助開發(fā)者布局,這些工具十分的方便僵缺,我在日常開發(fā)工作中也是使用的非常頻繁
Guideline(參考線)
Guideline是一條參考線胡桃,可以幫助開發(fā)者進(jìn)行輔助定位,并且實(shí)際上它并不會(huì)真正顯示在布局中磕潮,像是數(shù)學(xué)幾何中的輔助線一樣翠胰,使用起來十分方便,出場(chǎng)率很高自脯,Guideline也可以用來做一些百分比分割之類的需求之景,有著很好的屏幕適配效果,Guideline有水平和垂直方向之分膏潮,位置可以使用針對(duì)父級(jí)的百分比或者針對(duì)父級(jí)位置的距離
android:orientation="horizontal|vertical" 輔助線的對(duì)齊方式
app:layout_constraintGuide_percent="0-1" 距離父級(jí)寬度或高度的百分比(小數(shù)形式)
app:layout_constraintGuide_begin="" 距離父級(jí)起始位置的距離(左側(cè)或頂部)
app:layout_constraintGuide_end="" 距離父級(jí)結(jié)束位置的距離(右側(cè)或底部)
<?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"
android:background="#DAF3FE"
tools:context=".MainActivity"
tools:ignore="HardcodedText">
<androidx.constraintlayout.widget.Guideline
android:id="@+id/Guideline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.5" />
<TextView
android:id="@+id/A"
android:layout_width="120dp"
android:layout_height="80dp"
android:background="@drawable/tv_bg"
android:gravity="center"
android:text="A"
android:textColor="@color/black"
android:textSize="25sp"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/Guideline" />
</androidx.constraintlayout.widget.ConstraintLayout>
上圖中設(shè)置了一條水平方向位置在父級(jí)垂直方向0.5(50%)的Guideline锻狗,控件A的頂部依賴于Guideline,這樣無論布局如何更改焕参,Guideline的位置始終都會(huì)是父級(jí)垂直方向50%的位置轻纪,控件A的位置也不會(huì)偏離預(yù)設(shè)
Barrier(屏障)
這個(gè)Barrier和Guideline一樣,也不會(huì)實(shí)際出現(xiàn)在布局中叠纷,它的作用如同其名刻帚,形成一個(gè)屏障、障礙讲岁,使用也非常多我擂。這里借助constraintlayout網(wǎng)站(https://constraintlayout.github.io/basics/barriers.html)來講解Barrier。 當(dāng)我們創(chuàng)建布局時(shí)缓艳,有時(shí)會(huì)遇到布局可以根據(jù)本地化而更改的情況校摩。這里借助有一個(gè)非常簡(jiǎn)單的例子:
這里的問題在于textView3仍然是相對(duì)于textView1的交胚,所以textView2直接插入了textView3中。在設(shè)計(jì)視圖里看起來更明顯(白色背景的那個(gè))盈电。比較直接的解決辦法是使用TableLayout蝴簇,或者把 textView1 & textView2 包裹在一個(gè)垂直的,android:layout_width="wrap_content" 的 LinearLayout中匆帚。然后讓textView3約束在這個(gè)LinearLayout的后面熬词。但是我們有更好的辦法:Barriers。Barriers的配置屬性如下:
用于控制Barrier相對(duì)于給定的View的位置
app:barrierDirection="top|bottom|left|right|start|end"
取值是要依賴的控件的id吸重,Barrier將會(huì)使用ids中最大的一個(gè)的寬/高作為自己的位置
app:constraint_referenced_ids="id,id" </pre>
修改過后的代碼如下:
<?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/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:text="@string/warehouse"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="8dp"
android:text="@string/hospital"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView1" />
<androidx.constraintlayout.widget.Barrier
android:id="@+id/barrier7"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:barrierDirection="end"
app:constraint_referenced_ids="textView2,textView1" />
<TextView
android:id="@+id/textView3"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:text="@string/lorem_ipsum"
app:layout_constraintStart_toEndOf="@+id/barrier7"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
為了看到整體的效果互拾,可以切換語(yǔ)言,此時(shí)你會(huì)看到Barrier會(huì)自動(dòng)位于較寬的那個(gè)textView后面晤锹,也就間接讓textView3也位于了正確的位置摩幔。
Group(組)
工作當(dāng)中常常會(huì)有很多個(gè)控件同時(shí)隱藏或者顯示的場(chǎng)景,傳統(tǒng)做法要么是進(jìn)行嵌套鞭铆,對(duì)父布局進(jìn)行隱藏或顯示或衡,要么就是一個(gè)一個(gè)設(shè)置,這顯然都不是很好的辦法车遂,ConstraintLayout中的Group就是來解決這個(gè)問題的封断。Group的作用就是可以對(duì)一組控件同時(shí)隱藏或顯示,沒有其他的作用舶担,它的屬性如下:
app:constraint_referenced_ids="id,id" 加入組的控件id
<?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"
android:background="#DAF3FE"
tools:context=".MainActivity"
tools:ignore="HardcodedText">
<TextView
android:id="@+id/A"
android:layout_width="100dp"
android:layout_height="60dp"
android:layout_marginTop="56dp"
android:background="@drawable/tv_bg"
android:gravity="center"
android:text="A"
android:textColor="@color/black"
android:textSize="25sp"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.115"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/B"
android:layout_width="100dp"
android:layout_height="60dp"
android:layout_marginTop="280dp"
android:background="@drawable/tv_bg"
android:gravity="center"
android:text="B"
android:textColor="@color/black"
android:textSize="25sp"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.758"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/C"
android:layout_width="100dp"
android:layout_height="60dp"
android:layout_marginTop="164dp"
android:background="@drawable/tv_bg"
android:gravity="center"
android:text="C"
android:textColor="@color/black"
android:textSize="25sp"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.437"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.constraintlayout.widget.Group
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="visible"
app:constraint_referenced_ids="A,B,C" />
</androidx.constraintlayout.widget.ConstraintLayout>
A坡疼、B、C三個(gè)view衣陶,受Group控制柄瑰,當(dāng)Group的visibility為visible時(shí),它們都是正常顯示的剪况,設(shè)置為gone時(shí)教沾,它們都會(huì)隱藏:Placeholder(占位符)
Placeholder的作用就是占位,它可以在布局中占好位置译断,通過app:content=""屬性授翻,或者動(dòng)態(tài)調(diào)用setContent()設(shè)置內(nèi)容,來讓某個(gè)控件移動(dòng)到此占位符中<?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"
android:background="#DAF3FE"
tools:context=".MainActivity"
tools:ignore="HardcodedText">
<TextView
android:id="@+id/A"
android:layout_width="100dp"
android:layout_height="60dp"
android:background="@drawable/tv_bg"
android:gravity="center"
android:text="A"
android:textColor="@color/black"
android:textSize="25sp"
android:textStyle="bold"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.constraintlayout.widget.Placeholder
android:layout_width="100dp"
android:layout_height="60dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
當(dāng)我們?cè)O(shè)置app:content="@+id/A"或者調(diào)用setContent()時(shí),控件A就會(huì)被移動(dòng)到Placeholder中堪唐,當(dāng)然在布局中使用app:content=""顯然就失去了它的作用巡语。
Flow(流式虛擬布局)
Flow是用于構(gòu)建鏈的新虛擬布局,當(dāng)鏈用完時(shí)可以纏繞到下一行甚至屏幕的另一部分淮菠。當(dāng)您在一個(gè)鏈中布置多個(gè)項(xiàng)目時(shí)男公,這很有用,但是您不確定容器在運(yùn)行時(shí)的大小兜材。您可以使用它來根據(jù)應(yīng)用程序中的動(dòng)態(tài)尺寸(例如旋轉(zhuǎn)時(shí)的屏幕寬度)構(gòu)建布局理澎。Flow是一種虛擬布局。在ConstraintLayout中曙寡,虛擬布局(Virtual layouts)作為virtual view group的角色參與約束和布局中,但是它們并不會(huì)作為視圖添加到視圖層級(jí)結(jié)構(gòu)中寇荧,而是僅僅引用其它視圖來輔助它們?cè)诓季窒到y(tǒng)中完成各自的布局功能举庶。下面使用動(dòng)畫來展示Flow創(chuàng)建多個(gè)鏈將布局元素充裕地填充一整行:<?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"
android:background="#DAF3FE"
tools:context=".MainActivity"
tools:ignore="HardcodedText">
<TextView
android:id="@+id/A"
android:layout_width="60dp"
android:layout_height="60dp"
android:background="@drawable/tv_bg"
android:gravity="center"
android:text="A"
android:textColor="@color/black"
android:textSize="25sp"
android:textStyle="bold" />
<TextView
android:id="@+id/B"
android:layout_width="60dp"
android:layout_height="60dp"
android:background="@drawable/tv_bg"
android:gravity="center"
android:text="B"
android:textColor="@color/black"
android:textSize="25sp"
android:textStyle="bold" />
<TextView
android:id="@+id/C"
android:layout_width="60dp"
android:layout_height="60dp"
android:background="@drawable/tv_bg"
android:gravity="center"
android:text="C"
android:textColor="@color/black"
android:textSize="25sp"
android:textStyle="bold" />
<TextView
android:id="@+id/D"
android:layout_width="60dp"
android:layout_height="60dp"
android:background="@drawable/tv_bg"
android:gravity="center"
android:text="D"
android:textColor="@color/black"
android:textSize="25sp"
android:textStyle="bold" />
<TextView
android:id="@+id/E"
android:layout_width="60dp"
android:layout_height="60dp"
android:background="@drawable/tv_bg"
android:gravity="center"
android:text="E"
android:textColor="@color/black"
android:textSize="25sp"
android:textStyle="bold" />
<androidx.constraintlayout.helper.widget.Flow
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:constraint_referenced_ids="A,B,C,D,E"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
-
鏈約束
當(dāng)flow_wrapMode的值是chian或aligned時(shí)蕊唐,我們還可以針對(duì)不同的鏈進(jìn)行配置,這里就不一一展示效果了烁设,具體的屬性如下:
app:flow_horizontalStyle="packed|spread|spread_inside" 所有水平鏈的配置
app:flow_verticalStyle="packed|spread|spread_inside" 所有垂直鏈的配置
app:flow_firstHorizontalStyle="packed|spread|spread_inside" 第一條水平鏈的配置替梨,其他條不生效
app:flow_firstVerticalStyle="packed|spread|spread_inside" 第一條垂直鏈的配置,其他條不生效
app:flow_lastHorizontalStyle="packed|spread|spread_inside" 最后一條水平鏈的配置装黑,其他條不生效
app:flow_lastVerticalStyle="packed|spread|spread_inside" 最后一條垂直鏈的配置副瀑,其他條不生效
-
對(duì)齊約束
上面展示的都是相同大小的view,那么不同大小view的對(duì)齊方式恋谭,F(xiàn)low也提供了相應(yīng)的屬性進(jìn)行配置(flow_wrapMode="aligned"時(shí)糠睡,我試著沒有效果)
使用flow_verticalAlign時(shí)均抽,要求orientation的方向是horizontal,而使用flow_horizontalAlign時(shí)母截,要求orientation的方向是vertical下面展示下各個(gè)效果:top:頂對(duì)齊、bottom:底對(duì)齊疚颊、center:中心對(duì)齊狈孔、baseline:基線對(duì)齊
app:flow_verticalAlign="top|bottom|c(diǎn)enter|baseline"
start:開始對(duì)齊、end:結(jié)尾對(duì)齊材义、center:中心對(duì)齊
app:flow_horizontalAlign="start|end|center" </pre>
<androidx.constraintlayout.helper.widget.Flow
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
app:constraint_referenced_ids="A,B,C,D,E,F,G,H,I,J"
app:flow_verticalAlign="top"
app:flow_wrapMode="chain"
app:layout_constraintTop_toTopOf="parent" />
<androidx.constraintlayout.helper.widget.Flow
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
app:constraint_referenced_ids="A,B,C,D,E,F,G,H,I,J"
app:flow_verticalAlign="bottom"
app:flow_wrapMode="chain"
app:layout_constraintTop_toTopOf="parent" />
<androidx.constraintlayout.helper.widget.Flow
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
app:constraint_referenced_ids="A,B,C,D,E,F,G,H,I,J"
app:flow_verticalAlign="center"
app:flow_wrapMode="chain"
app:layout_constraintTop_toTopOf="parent" />
<androidx.constraintlayout.helper.widget.Flow
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
app:constraint_referenced_ids="A,B,C,D,E,F,G,H,I,J"
app:flow_verticalAlign="baseline"
app:flow_wrapMode="chain"
app:layout_constraintTop_toTopOf="parent" />
垂直方向排列這里就不再作過多的展示了
-
數(shù)量約束
Layer(層布局)
Layer繼承自ConstraintHelper喘漏,是一個(gè)約束助手护蝶,相對(duì)于Flow來說,Layer的使用較為簡(jiǎn)單翩迈,常用來增加背景持灰,或者共同動(dòng)畫,圖層 (Layer) 在布局期間會(huì)調(diào)整大小负饲,其大小會(huì)根據(jù)其引用的所有視圖進(jìn)行調(diào)整堤魁,代碼的先后順序也會(huì)決定著它的位置,如果代碼在所有引用view的最后面返十,那么它就會(huì)在所有view的最上面妥泉,反之則是最下面,在最上面的時(shí)候如果添加背景洞坑,就會(huì)把引用的view覆蓋掉盲链,下面展示下添加背景的例子,做動(dòng)畫的例子這里不再展示了<?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"
android:background="#DAF3FE"
tools:context=".MainActivity"
tools:ignore="HardcodedText">
<androidx.constraintlayout.helper.widget.Layer
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/common_rect_white_100_10"
android:padding="10dp"
app:constraint_referenced_ids="AndroidImg,NameTv" />
<ImageView
android:id="@+id/AndroidImg"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:src="@drawable/android"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/NameTv"
android:layout_width="100dp"
android:layout_height="40dp"
android:gravity="center"
android:text="Android"
android:textColor="@color/black"
android:textSize="25sp"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="@id/AndroidImg"
app:layout_constraintStart_toStartOf="@id/AndroidImg"
app:layout_constraintTop_toBottomOf="@id/AndroidImg" />
</androidx.constraintlayout.widget.ConstraintLayout>
可以看到迟杂,當(dāng)Layer的代碼在所有引用view的上面時(shí)刽沾,效果是正常的,因?yàn)榇藭r(shí)所有的view都在Layer的上面排拷,下面我們來看一下Layer代碼在最后面時(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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#DAF3FE"
tools:context=".MainActivity"
tools:ignore="HardcodedText">
<ImageView
android:id="@+id/AndroidImg"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:src="@drawable/android"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/NameTv"
android:layout_width="100dp"
android:layout_height="40dp"
android:gravity="center"
android:text="Android"
android:textColor="@color/black"
android:textSize="25sp"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="@id/AndroidImg"
app:layout_constraintStart_toStartOf="@id/AndroidImg"
app:layout_constraintTop_toBottomOf="@id/AndroidImg" />
<androidx.constraintlayout.helper.widget.Layer
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/common_rect_white_100_10"
android:padding="10dp"
app:constraint_referenced_ids="AndroidImg,NameTv" />
</androidx.constraintlayout.widget.ConstraintLayout>
我們可以看到侧漓,此時(shí)Layer已經(jīng)把所有的view覆蓋住了
ImageFilterButton & ImageFilterView
ImageFilterButton和ImageFilterView是兩個(gè)控件,他們之間的關(guān)系就和ImageButton與ImageView是一樣的监氢,所以這里就只拿ImageFilterView來做講解布蔗。從名字上來看,它們的定位是和過濾有關(guān)系的忙菠,它們的大致作用有兩部分何鸡,一是可以用來做圓角圖片,二是可以疊加圖片資源進(jìn)行混合過濾牛欢,下面一一展示:
-
圓角圖片
<?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"
android:background="#DAF3FE"
tools:context=".MainActivity"
tools:ignore="HardcodedText">
<androidx.constraintlayout.utils.widget.ImageFilterView
android:layout_width="100dp"
android:layout_height="100dp"
android:src="@drawable/mi"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:roundPercent="0.7" />
</androidx.constraintlayout.widget.ConstraintLayout>
雖然和小米新logo的圓弧不太一樣鳄炉,不過這也不是我們考慮的地方杜耙,可以看到我們使用roundPercent設(shè)置了圓角為0.7(70%),實(shí)現(xiàn)一個(gè)圓角圖片就是如此簡(jiǎn)單拂盯。
-
圖片過濾
MockView
你家產(chǎn)品經(jīng)理經(jīng)常會(huì)給你畫原型圖两嘴,但這絕對(duì)不是他們的專屬,我們也有自己的原型圖族壳,一個(gè)成熟的程序員要學(xué)會(huì)給自己的產(chǎn)品經(jīng)理畫大餅憔辫,我們可以使用MockView來充當(dāng)原型圖,下面看例子:<?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"
android:background="#DAF3FE"
tools:context=".MainActivity"
tools:ignore="HardcodedText">
<androidx.constraintlayout.utils.widget.MockView
android:id="@+id/Avatar"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_marginStart="80dp"
android:layout_marginTop="100dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.constraintlayout.utils.widget.MockView
android:id="@+id/Name"
android:layout_width="100dp"
android:layout_height="30dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/Avatar"
app:layout_constraintTop_toTopOf="@id/Avatar" />
<androidx.constraintlayout.utils.widget.MockView
android:id="@+id/Age"
android:layout_width="100dp"
android:layout_height="30dp"
app:layout_constraintBottom_toBottomOf="@id/Avatar"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/Avatar" />
</androidx.constraintlayout.widget.ConstraintLayout>
ConstraintProperties(流式API)
2.0 提供了ConstraintProperties可以使用流式 API修改屬性
val properties = ConstraintProperties(findViewById(R.id.image))
properties.translationZ(32f)
.margin(ConstraintSet.START, 43)
.apply()
MotionLayout
Motion Layout是Constraint Layout 2.0中最令人期待的功能之一仿荆。它提供了一個(gè)豐富的動(dòng)畫系統(tǒng)來協(xié)調(diào)多個(gè)視圖之間的動(dòng)畫效果贰您。MotionLayout基于ConstraintLayout,并在其之上進(jìn)行了擴(kuò)展拢操,允許您在多組約束 (或者ConstraintSets) 之間進(jìn)行動(dòng)畫的處理锦亦。您可以對(duì)視圖的移動(dòng)、滾動(dòng)令境、縮放杠园、旋轉(zhuǎn)、淡入淡出等一系列動(dòng)畫行為進(jìn)行自定義舔庶,甚至可以定義各個(gè)動(dòng)畫本身的自定義屬性抛蚁。它還可以處理手勢(shì)操作所產(chǎn)生的物理移動(dòng)效果,以及控制動(dòng)畫的速度惕橙。使用MotionLayout構(gòu)建的動(dòng)畫是可追溯且可逆的瞧甩,這意味著您可以隨意切換到動(dòng)畫過程中任意一個(gè)點(diǎn),甚至可以倒著執(zhí)行動(dòng)畫效果弥鹦。Android Studio集成了 Motion Editor(動(dòng)作編輯器)肚逸,可以利用它來操作MotionLayout對(duì)動(dòng)畫進(jìn)行生成、預(yù)覽和編輯等操作。這樣一來朦促,在協(xié)調(diào)多個(gè)視圖的動(dòng)畫時(shí)膝晾,就可以做到對(duì)各個(gè)細(xì)節(jié)進(jìn)行精細(xì)操控。由于我自己也沒有用過思灰,且說起來篇幅也挺大玷犹,這里就不再講解MotionLayout(主要是我也不會(huì))/ 結(jié)語(yǔ) /至此,關(guān)于Constraint Layout的內(nèi)容基本已經(jīng)介紹完畢洒疚,因?yàn)閮?nèi)容較多歹颓,代碼示例代碼和圖片也比較多,一次性看完實(shí)屬不易油湖,可以點(diǎn)擊收藏供以后翻閱巍扛,寫這篇文章我是經(jīng)歷了無數(shù)次放棄和重新拾起,內(nèi)容確實(shí)太多了乏德,再加上也已經(jīng)有很多不錯(cuò)的博文來介紹Constraint Layout撤奸,但是他們的肯定沒有我的全!??如有錯(cuò)誤請(qǐng)及時(shí)聯(lián)系我喊括,我會(huì)盡快修改更正胧瓜。
新小夢(mèng):Constraintlayout 2.0:你們要的更新來了https://juejin.cn/post/6854573221312725000
谷歌開發(fā)者:Constraint Layout 2.0 用法詳解https://zhuanlan.zhihu.com/p/336387890
constraintlayout網(wǎng)站https://constraintlayout.com/basics/barriers.html